# Bedrock Branding Implementation Guide
A comprehensive guide to implementing the Bedrock branding system (app icon and launch screen) in your iOS app.
## Table of Contents
1. [Overview](#overview)
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)
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)
9. [Configuration Reference](#configuration-reference)
10. [Complete Example](#complete-example)
11. [Troubleshooting](#troubleshooting)
---
## Overview
The Bedrock branding system provides a fully customizable app icon and launch screen that can be configured for any type of app. All visual elements are configurable through Swift code.
### Key Features
- **Customizable gradients**: Primary and secondary colors for backgrounds
- **Configurable icons**: Use any SF Symbols for your app identity
- **Multiple pattern styles**: Dots, grid, radial glow, or no pattern
- **Layout flexibility**: Icon above title, title above icon, icon only, or title only
- **Animated launch**: Smooth fade-in animations with configurable timing
- **Icon generator**: Built-in tool to export 1024×1024 PNG for App Store
---
## What's Included
The branding system consists of these files in `Bedrock/Sources/Bedrock/Branding/`:
| File | Purpose |
|------|---------|
| `AppIconView.swift` | Renders the app icon design |
| `LaunchScreenView.swift` | Animated launch screen view |
| `AppLaunchView.swift` | Wrapper that shows launch screen before main content |
| `IconGeneratorView.swift` | Development tool to export icon images |
| `IconRenderer.swift` | Utility to render views to images |
| `BrandingPreviewView.swift` | Preview tool for icons and launch screens |
---
## Step 1: Create BrandingConfig.swift
Create a new Swift file in your app's `Shared/` folder called `BrandingConfig.swift`. This file defines your app's branding.
### Template
```swift
//
// BrandingConfig.swift
// YourApp
//
// App-specific branding configurations for icons and launch screens.
//
import SwiftUI
import Bedrock
// MARK: - App Branding Colors
extension Color {
/// Your app's branding colors for icon and launch screen.
enum Branding {
/// Primary gradient color (top/leading).
static let primary = Color(red: 0.3, green: 0.5, blue: 0.8)
/// Secondary gradient color (bottom/trailing).
static let secondary = Color(red: 0.15, green: 0.3, blue: 0.5)
/// Accent color for icons and highlights.
static let accent = Color.white
}
}
// MARK: - App Icon Configuration
extension AppIconConfig {
/// Your app's icon configuration.
static let yourApp = AppIconConfig(
title: "YOUR APP",
subtitle: nil, // Optional: text below icon
iconSymbol: "star.fill", // SF Symbol name
primaryColor: Color.Branding.primary,
secondaryColor: Color.Branding.secondary,
accentColor: Color.Branding.accent
)
}
// MARK: - Launch Screen Configuration
extension LaunchScreenConfig {
/// Your app's launch screen configuration.
static let yourApp = LaunchScreenConfig(
title: "YOUR APP",
tagline: "Your tagline here",
iconSymbols: ["star.fill"],
primaryColor: Color.Branding.primary,
secondaryColor: Color.Branding.secondary,
accentColor: Color.Branding.accent
)
}
```
---
## Step 2: Add Launch Screen to App Entry Point
Update your `@main` App struct to wrap your content with `AppLaunchView`.
### Before
```swift
@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
```
### After
```swift
import SwiftUI
import Bedrock
@main
struct YourApp: App {
var body: some Scene {
WindowGroup {
ZStack {
// Base background matching launch screen - prevents flash
Color.Branding.primary
.ignoresSafeArea()
AppLaunchView(config: .yourApp) {
ContentView()
}
}
}
}
}
```
**What this does:**
- Shows an animated launch screen for ~2 seconds
- Fades smoothly into your main content
- Creates a polished, professional app opening experience
**Why the ZStack?**
The `AppLaunchView` renders your main content underneath the launch overlay from the start. Without the base `Color.Branding.primary` layer, the main content's background (often white) can flash briefly before the launch screen covers it. The ZStack ensures the entire window is filled with your brand color from the first frame.
---
## Step 3: Set Launch Screen Background Color
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.
### 3.1 Create the Color Asset
Create a folder in your asset catalog:
```
YourApp/Resources/Assets.xcassets/LaunchBackground.colorset/Contents.json
```
With this content (update RGB values to match your `Color.Branding.primary`):
**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`:
```xml
UILaunchScreen
UIColorName
LaunchBackground
```
This explicitly tells iOS to use your color asset for the system launch screen background.
### 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;
```
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
**Important:** After making this change:
1. Clean build (Cmd+Shift+K)
2. Delete app from simulator/device
3. Build and run again
---
## Step 4: Add Branding Tools to Settings (Optional)
Add debug tools to your settings view for generating and previewing icons during development.
### Add to SettingsView
```swift
import SwiftUI
import Bedrock
struct SettingsView: View {
var body: some View {
NavigationStack {
List {
// ... your normal settings ...
#if DEBUG
Section("Debug") {
NavigationLink("Icon Generator") {
IconGeneratorView(config: .yourApp, appName: "YourApp")
}
NavigationLink("Branding Preview") {
BrandingPreviewView(
iconConfig: .yourApp,
launchConfig: .yourApp,
appName: "YourApp"
)
}
}
#endif
}
}
}
}
```
**Important:** Wrap in `#if DEBUG` so these tools are excluded from App Store builds.
---
## Step 5: Generate Your App Icon
### Using IconGeneratorView (Recommended)
1. **Build and run your app** in DEBUG mode
2. **Open Settings** → Debug section
3. **Tap "Icon Generator"**
4. **Tap "Generate & Save Icon"**
5. **Wait for confirmation**: "✅ Icon saved to Documents folder!"
### Retrieve the Icon
**On Simulator:**
1. Open Finder
2. Go to: `~/Library/Developer/CoreSimulator/Devices/`
3. Find your simulator device folder (sorted by date)
4. Navigate to: `data/Containers/Data/Application/[YourApp-UUID]/Documents/`
5. Copy `AppIcon.png`
**On Physical Device:**
1. Open **Files** app on your device
2. Navigate to: **On My iPhone** → **YourApp**
3. Find `AppIcon.png`
4. **AirDrop** or **share** to your Mac
**Alternative (Xcode):**
1. Go to **Window** → **Devices and Simulators**
2. Select your device/simulator
3. Find your app → Click **⚙️ gear** → **Download Container**
4. Right-click downloaded file → **Show Package Contents**
5. Navigate to `AppData/Documents/` and copy `AppIcon.png`
---
## Step 6: Add Icon to Xcode Assets
1. **Open your Xcode project**
2. **Navigate to** `Assets.xcassets` → `AppIcon`
3. **Drag `AppIcon.png`** into the **1024×1024** slot
4. Xcode automatically generates all required sizes
**Verify:**
1. Clean build and run
2. Check home screen for new icon
3. If unchanged, delete app and reinstall
---
## Configuration Reference
### AppIconConfig
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `title` | `String` | Required | App name (uppercase recommended) |
| `subtitle` | `String?` | `nil` | Optional text below icon |
| `iconSymbol` | `String` | Required | SF Symbol name |
| `primaryColor` | `Color` | Blue | Top-left gradient color |
| `secondaryColor` | `Color` | Dark blue | Bottom-right gradient color |
| `accentColor` | `Color` | Light blue | Icon and text highlight color |
### LaunchScreenConfig
| Property | Type | Default | Description |
|----------|------|---------|-------------|
| `title` | `String` | Required | App name displayed on launch |
| `subtitle` | `String?` | `nil` | Large text (like "PRO" or version) |
| `tagline` | `String?` | `nil` | Small text at bottom of screen |
| `iconSymbols` | `[String]` | `["star.fill"]` | Array of SF Symbol names |
| `cornerSymbol` | `String?` | `nil` | Symbol for corner decorations (nil = none) |
| `decorativeSymbol` | `String?` | `"circle.fill"` | Symbol in decorative line (nil = hide line) |
| `patternStyle` | `LaunchPatternStyle` | `.dots` | Background pattern style |
| `layoutStyle` | `LaunchLayoutStyle` | `.iconAboveTitle` | Content layout arrangement |
| `primaryColor` | `Color` | Blue-gray | Top gradient color |
| `secondaryColor` | `Color` | Dark blue | Bottom gradient color |
| `accentColor` | `Color` | Light blue | Icons and highlights |
| `titleColor` | `Color` | `.white` | Title text color |
| `iconSize` | `CGFloat` | `48` | Size of icon symbols |
| `titleSize` | `CGFloat` | `42` | Size of title text |
| `subtitleSize` | `CGFloat` | `72` | Size of subtitle text |
| `iconSpacing` | `CGFloat` | `8` | Spacing between icons |
| `animationDuration` | `Double` | `0.6` | Fade-in animation duration |
| `showLoadingIndicator` | `Bool` | `false` | Show spinner at bottom |
### LaunchPatternStyle
| Value | Description |
|-------|-------------|
| `.none` | Clean background, no pattern |
| `.dots` | Subtle dot pattern (default) |
| `.grid` | Grid lines pattern |
| `.radial` | Radial gradient glow from center |
### LaunchLayoutStyle
| Value | Description |
|-------|-------------|
| `.iconAboveTitle` | Icons at top, title below (default) |
| `.titleAboveIcon` | Title at top, icons below |
| `.iconOnly` | Only show icons, no text |
| `.titleOnly` | Only show text, no icons |
---
## Complete Example
Here's a full example for a camera app:
### File: `YourApp/Shared/BrandingConfig.swift`
```swift
import SwiftUI
import Bedrock
// MARK: - App Branding Colors
extension Color {
enum Branding {
// Vibrant magenta/rose gradient
static let primary = Color(red: 0.85, green: 0.25, blue: 0.45)
static let secondary = Color(red: 0.45, green: 0.12, blue: 0.35)
static let accent = Color.white
}
}
// MARK: - App Icon Configuration
extension AppIconConfig {
static let myCamera = AppIconConfig(
title: "CAMERA",
subtitle: "PRO",
iconSymbol: "camera.fill",
primaryColor: Color.Branding.primary,
secondaryColor: Color.Branding.secondary,
accentColor: Color.Branding.accent
)
}
// MARK: - Launch Screen Configuration
extension LaunchScreenConfig {
static let myCamera = LaunchScreenConfig(
title: "CAMERA PRO",
tagline: "Capture the Moment",
iconSymbols: ["camera.fill", "sparkles"],
cornerSymbol: "sparkle", // Sparkles in corners
decorativeSymbol: "circle.fill", // Circle in decorative line
patternStyle: .radial, // Radial glow effect
layoutStyle: .iconAboveTitle,
primaryColor: Color.Branding.primary,
secondaryColor: Color.Branding.secondary,
accentColor: Color.Branding.accent,
titleColor: .white,
iconSize: 52,
titleSize: 38,
iconSpacing: 12,
animationDuration: 0.6
)
}
```
### File: `YourApp/App/MyCameraApp.swift`
```swift
import SwiftUI
import Bedrock
@main
struct MyCameraApp: App {
var body: some Scene {
WindowGroup {
ZStack {
// Base background matching launch screen - prevents flash
Color.Branding.primary
.ignoresSafeArea()
AppLaunchView(config: .myCamera) {
ContentView()
}
}
}
}
}
```
---
## Troubleshooting
### 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.
**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`
**Critical:** After any launch screen changes:
1. Clean build (Cmd+Shift+K)
2. Delete app from simulator/device completely
3. Quit and restart the simulator
4. Build and run fresh
iOS caches the launch screen aggressively.
### Can't find types like `AppIconConfig`
**Solution:** Make sure you have `import Bedrock` at the top of your file.
### Launch screen doesn't appear
**Solution:**
- Verify `AppLaunchView` wraps your content in the App struct
- Check that you're using the correct config name (e.g., `.myCamera`)
- Ensure the config extension is defined in `BrandingConfig.swift`
### Icon looks different than preview
**Explanation:** iOS applies a superellipse mask to all app icons.
**Solution:** Don't add your own rounded corners—iOS does this automatically.
### "Icon saved" but can't find file
**Solution:**
1. Open **Files** app on device/simulator
2. Navigate to: **On My iPhone/iPad** → **[Your App Name]**
3. If folder doesn't exist, the app may need Files access
**Alternative:** Use Xcode's Devices and Simulators window to download the app container.
### Icon doesn't update in simulator
**Solution:**
1. Clean build folder: Product → Clean Build Folder (Cmd+Shift+K)
2. Delete app from simulator
3. Rebuild and run
### DEBUG section not showing in settings
**Solution:**
- Ensure you're running a DEBUG build (not Release)
- Check that code is wrapped in `#if DEBUG ... #endif`
- Verify your settings view is inside a `NavigationStack`
---
## Color Palette Ideas
### Professional Blue
```swift
primaryColor: Color(red: 0.15, green: 0.30, blue: 0.55)
secondaryColor: Color(red: 0.08, green: 0.15, blue: 0.30)
accentColor: .white
```
### Vibrant Pink/Magenta
```swift
primaryColor: Color(red: 0.85, green: 0.25, blue: 0.45)
secondaryColor: Color(red: 0.45, green: 0.12, blue: 0.35)
accentColor: .white
```
### Nature Green
```swift
primaryColor: Color(red: 0.20, green: 0.55, blue: 0.35)
secondaryColor: Color(red: 0.10, green: 0.30, blue: 0.20)
accentColor: Color(red: 0.85, green: 0.95, blue: 0.85)
```
### Warm Orange/Gold
```swift
primaryColor: Color(red: 0.95, green: 0.60, blue: 0.20)
secondaryColor: Color(red: 0.70, green: 0.35, blue: 0.10)
accentColor: .white
```
### Dark/Minimal
```swift
primaryColor: Color(red: 0.12, green: 0.12, blue: 0.15)
secondaryColor: .black
accentColor: .white
patternStyle: .none
```
---
## SF Symbol Recommendations
### Photography/Camera
- `camera.fill`, `camera.circle.fill`
- `photo.fill`, `photo.stack.fill`
- `sparkles`, `wand.and.stars`
### Social/Communication
- `message.fill`, `bubble.left.fill`
- `person.fill`, `person.2.fill`
- `heart.fill`, `star.fill`
### Productivity
- `doc.fill`, `folder.fill`
- `checkmark.circle.fill`
- `calendar`, `clock.fill`
### Music/Media
- `music.note`, `waveform`
- `play.fill`, `headphones`
- `mic.fill`, `speaker.wave.2.fill`
### Utility
- `gearshape.fill`, `wrench.fill`
- `magnifyingglass`, `location.fill`
- `bolt.fill`, `battery.100`
---
## Summary Checklist
- [ ] 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`
- [ ] Clean build, delete app, and reinstall to test launch screen
- [ ] 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
---
**Happy Branding! 🎨✨**