Bedrock/Sources/Bedrock/Branding/BRANDING_GUIDE.md

18 KiB
Raw Blame History

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
  2. What's Included
  3. Step 1: Create BrandingConfig.swift
  4. Step 2: Add Launch Screen to App Entry Point
  5. Step 3: Set Launch Screen Background Color
  6. Step 4: Add Branding Tools to Settings (Optional)
  7. Step 5: Generate Your App Icon
  8. Step 6: Add Icon to Xcode Assets
  9. Configuration Reference
  10. Complete Example
  11. 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

//
//  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

@main
struct YourApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

After

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.

{
  "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:

<key>UILaunchScreen</key>
<dict>
    <key>UIColorName</key>
    <string>LaunchBackground</string>
</dict>

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

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

  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 iPhoneYourApp
  3. Find AppIcon.png
  4. AirDrop or share to your Mac

Alternative (Xcode):

  1. Go to WindowDevices and Simulators
  2. Select your device/simulator
  3. Find your app → Click ⚙️ gearDownload 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.xcassetsAppIcon
  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

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

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 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

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

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

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

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

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! 🎨