Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>

This commit is contained in:
Matt Bruce 2026-01-12 08:11:21 -06:00
parent 9fcb698b7b
commit 05f0907e0c
2 changed files with 175 additions and 79 deletions

View File

@ -15,6 +15,61 @@ Bedrock is designed to be the foundation upon which apps are built, providing:
- **Visual Effects**: Confetti celebrations, pulsing animations
- **Utilities**: Device detection, debugging tools, and more
---
## 📚 Implementation Guides for AI Agents
> **Before implementing any Bedrock features in a new app, read the relevant guide(s) below.** Each guide contains step-by-step instructions, templates, and troubleshooting information.
### Guide Reference
| Guide | Path | Purpose |
|-------|------|---------|
| **Theme Guide** | [`Sources/Bedrock/Theme/THEME_GUIDE.md`](Sources/Bedrock/Theme/THEME_GUIDE.md) | Create custom color themes using Bedrock's protocol-based theming system |
| **Branding Guide** | [`Sources/Bedrock/Branding/BRANDING_GUIDE.md`](Sources/Bedrock/Branding/BRANDING_GUIDE.md) | Set up app icons, launch screens, and branded launch animations |
| **Settings Guide** | [`Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md`](Sources/Bedrock/Views/Settings/SETTINGS_GUIDE.md) | Build branded settings screens with reusable UI components |
### Implementation Checklist
Use this checklist when setting up a new app with Bedrock:
#### 🎨 Theming (Required for all apps)
- [ ] **Read**: `THEME_GUIDE.md`
- [ ] Create `[AppName]Theme.swift` in `Shared/Theme/`
- [ ] Define custom `SurfaceColorProvider` with your brand colors
- [ ] Define custom `AccentColorProvider` for interactive elements
- [ ] Create typealiases for easy access (e.g., `AppSurface`, `AppAccent`)
- [ ] Apply theme colors to all views (never use hardcoded colors)
#### 🚀 Branding & Launch Screen (Required for all apps)
- [ ] **Read**: `BRANDING_GUIDE.md`
- [ ] Create `BrandingConfig.swift` in `Shared/`
- [ ] Define `Color.Branding.primary`, `.secondary`, `.accent`
- [ ] Create `AppIconConfig` extension for your app
- [ ] Create `LaunchScreenConfig` extension for your app
- [ ] Create `LaunchScreen.storyboard` with matching brand color
- [ ] Add `INFOPLIST_KEY_UILaunchStoryboardName` to build settings
- [ ] Wrap app entry point with `AppLaunchView` inside a ZStack
- [ ] Generate and export app icon using `IconGeneratorView`
#### ⚙️ Settings Screen (When adding settings)
- [ ] **Read**: `SETTINGS_GUIDE.md`
- [ ] Use `SettingsToggle`, `SettingsSlider`, `SegmentedPicker` components
- [ ] Apply theme colors via `AppSurface`, `AppAccent`, etc.
- [ ] Use `SettingsCard` for grouped sections
- [ ] Use `SettingsNavigationRow` for navigation links
- [ ] Add `#if DEBUG` section for development tools
### Quick Start Order
When building a new app from scratch:
1. **First**: Read `THEME_GUIDE.md` → Create your app's color theme
2. **Second**: Read `BRANDING_GUIDE.md` → Set up icons and launch screen
3. **Third**: Read `SETTINGS_GUIDE.md` → Build your settings view
---
## Installation
Add Bedrock as a dependency in your `Package.swift`:

View File

@ -8,7 +8,7 @@ A comprehensive guide to implementing the Bedrock branding system (app icon and
2. [What's Included](#whats-included)
3. [Step 1: Create BrandingConfig.swift](#step-1-create-brandingconfigswift)
4. [Step 2: Add Launch Screen to App Entry Point](#step-2-add-launch-screen-to-app-entry-point)
5. [Step 3: Set Launch Screen Background Color](#step-3-set-launch-screen-background-color)
5. [Step 3: Native Launch Screen Setup](#step-3-native-launch-screen-setup)
6. [Step 4: Add Branding Tools to Settings (Optional)](#step-4-add-branding-tools-to-settings-optional)
7. [Step 5: Generate Your App Icon](#step-5-generate-your-app-icon)
8. [Step 6: Add Icon to Xcode Assets](#step-6-add-icon-to-xcode-assets)
@ -163,90 +163,113 @@ The `AppLaunchView` renders your main content underneath the launch overlay from
---
## Step 3: Set Launch Screen Background Color
## Step 3: Native Launch Screen Setup
To prevent a white flash before the SwiftUI launch screen appears, you need to set the system launch screen background color to match your branding.
> ⚠️ **IMPORTANT**
>
> **Do NOT rely solely on `INFOPLIST_KEY_UILaunchScreen_BackgroundColor`.** The generated `UILaunchScreen` dictionary may be empty, causing iOS to display a white screen before SwiftUI loads. Use a `LaunchScreen.storyboard` instead.
### 3.1 Create the Color Asset
To prevent a white/black flash before the SwiftUI launch screen appears, you need to configure the native iOS launch screen to match your branding.
Create a folder in your asset catalog:
```
YourApp/Resources/Assets.xcassets/LaunchBackground.colorset/Contents.json
```
### 3.1 Create LaunchScreen.storyboard
With this content (update RGB values to match your `Color.Branding.primary`):
Create a new file `LaunchScreen.storyboard` in your app target (e.g., `YourApp/Resources/LaunchScreen.storyboard`) with your theme's primary surface color as the background.
**Important:** Include both light and dark mode variants with identical colors to prevent issues when the device is in dark mode.
```json
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.220",
"green" : "0.120",
"red" : "0.050"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.220",
"green" : "0.120",
"red" : "0.050"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
```
### 3.2 Add UILaunchScreen to Info.plist
Add this dictionary to your app's `Info.plist`:
**Template** (replace `YOUR_RED`, `YOUR_GREEN`, `YOUR_BLUE` with your `Color.Branding.primary` RGB values):
```xml
<key>UILaunchScreen</key>
<dict>
<key>UIColorName</key>
<string>LaunchBackground</string>
</dict>
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22155" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22131"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" red="YOUR_RED" green="YOUR_GREEN" blue="YOUR_BLUE" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
</document>
```
This explicitly tells iOS to use your color asset for the system launch screen background.
**Example for magenta/rose branding (RGB: 0.85, 0.25, 0.45):**
### 3.3 Update Xcode Project Settings
In your `project.pbxproj`, add this line after `INFOPLIST_KEY_UILaunchScreen_Generation = YES;` in **both** Debug and Release build configurations:
```
"INFOPLIST_KEY_UILaunchScreen_BackgroundColor" = LaunchBackground;
```xml
<color key="backgroundColor" red="0.85" green="0.25" blue="0.45" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
```
Or in Xcode:
1. Select your target → Build Settings
2. Search for "Launch Screen"
3. Set "Asset Catalog Launch Image Set Name" or add User-Defined setting
### 3.2 Update Build Settings
**Important:** After making this change:
In your target's build settings, add/update:
```
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen
```
**Remove** these settings if present (they are unreliable):
- `INFOPLIST_KEY_UILaunchScreen_BackgroundColor`
- `INFOPLIST_KEY_UILaunchScreen_BackgroundColorName`
- `INFOPLIST_KEY_UILaunchScreen_Generation`
### 3.3 Match SwiftUI Backgrounds
Ensure all views maintain the same background color for a seamless transition from the native launch screen to SwiftUI:
**App Entry Point:**
```swift
@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ZStack {
// Base background matching launch screen - prevents flash
Color.Branding.primary
.ignoresSafeArea()
AppLaunchView(config: .yourApp) {
MainTabView()
}
}
}
}
}
```
**All Root Tab/Screen Views:**
```swift
struct ContentView: View {
var body: some View {
YourContent()
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.Branding.primary.ignoresSafeArea())
}
}
```
### Why Storyboard Over Generated Launch Screen?
The `GENERATE_INFOPLIST_FILE = YES` setting with `INFOPLIST_KEY_UILaunchScreen_BackgroundColor` does **not** reliably populate the `UILaunchScreen.UIColorName` key in the generated Info.plist. When this happens, iOS falls back to white (or black in dark mode).
A `LaunchScreen.storyboard` guarantees your color from the first frame because:
- The color is embedded directly in the storyboard file
- No runtime lookup of asset catalog colors is needed
- Works consistently across all iOS versions
**Important:** After making these changes:
1. Clean build (Cmd+Shift+K)
2. Delete app from simulator/device
3. Build and run again
@ -485,13 +508,13 @@ struct MyCameraApp: App {
### White/black flash before launch screen
**Cause:** iOS system launch screen doesn't match your branding colors, or the SwiftUI view hierarchy has a different background.
**Cause:** iOS system launch screen doesn't match your branding colors, or the generated `UILaunchScreen` dictionary is not being populated correctly.
**Solution:**
1. Follow [Step 3](#step-3-set-launch-screen-background-color) to add `LaunchBackground` color asset with both light and dark variants
2. Add `UILaunchScreen` dictionary to Info.plist (Step 3.2)
3. Wrap `AppLaunchView` in a `ZStack` with `Color.Branding.primary` as the base layer (Step 2)
4. Ensure the RGB values match **exactly** between the color asset and `Color.Branding.primary`
1. **Use a `LaunchScreen.storyboard`** instead of relying on `INFOPLIST_KEY_UILaunchScreen_BackgroundColor` (see [Step 3](#step-3-native-launch-screen-setup))
2. Wrap `AppLaunchView` in a `ZStack` with `Color.Branding.primary` as the base layer (Step 2)
3. Ensure the RGB values in the storyboard match **exactly** with `Color.Branding.primary`
4. Remove any `INFOPLIST_KEY_UILaunchScreen_*` settings from your project
**Critical:** After any launch screen changes:
1. Clean build (Cmd+Shift+K)
@ -501,6 +524,12 @@ struct MyCameraApp: App {
iOS caches the launch screen aggressively.
### Generated UILaunchScreen not working
**Cause:** The `INFOPLIST_KEY_UILaunchScreen_BackgroundColor` and `INFOPLIST_KEY_UILaunchScreen_Generation` settings do not reliably populate the `UILaunchScreen` dictionary in the generated Info.plist.
**Solution:** Use a `LaunchScreen.storyboard` instead. This is the only reliable method to ensure your launch screen color appears from the first frame. See [Step 3](#step-3-native-launch-screen-setup).
### Can't find types like `AppIconConfig`
**Solution:** Make sure you have `import Bedrock` at the top of your file.
@ -614,19 +643,31 @@ patternStyle: .none
## Summary Checklist
### Branding Configuration
- [ ] Create `BrandingConfig.swift` with your app's configurations
- [ ] Add `AppLaunchView` wrapper to your App entry point (inside ZStack with base color)
- [ ] Create `LaunchBackground.colorset` in asset catalog with **both light and dark variants**
- [ ] Add `UILaunchScreen` dictionary to `Info.plist` with `UIColorName`
- [ ] Add `INFOPLIST_KEY_UILaunchScreen_BackgroundColor` to project build settings
- [ ] Verify RGB values match exactly between color asset and `Color.Branding.primary`
- [ ] (Optional) Add debug section to settings with `IconGeneratorView` and `BrandingPreviewView`
- [ ] Define `Color.Branding.primary`, `.secondary`, and `.accent`
- [ ] Create `AppIconConfig` extension for your app
- [ ] Create `LaunchScreenConfig` extension for your app
### Launch Screen Setup
- [ ] Create `LaunchScreen.storyboard` with your brand color (Step 3.1)
- [ ] Add `INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen` to build settings
- [ ] Remove any `INFOPLIST_KEY_UILaunchScreen_*` settings if present
- [ ] Verify RGB values in storyboard match `Color.Branding.primary` exactly
### SwiftUI Integration
- [ ] Add `AppLaunchView` wrapper to your App entry point
- [ ] Wrap in ZStack with `Color.Branding.primary` as base layer
- [ ] Add matching background to all root tab/screen views
- [ ] Clean build, delete app, and reinstall to test launch screen
### App Icon
- [ ] (Optional) Add debug section to settings with `IconGeneratorView` and `BrandingPreviewView`
- [ ] Build and run in DEBUG mode
- [ ] Generate icon using Icon Generator tool
- [ ] Retrieve icon PNG from device/simulator
- [ ] Add 1024×1024 PNG to `Assets.xcassets/AppIcon`
- [ ] Clean build and reinstall to verify icon and launch screen
- [ ] Clean build and reinstall to verify icon
---