swiftgen integration

SwiftGen Integration — Expert Decisions

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "swiftgen integration" with this command: npx skills add kaakati/rails-enterprise-dev/kaakati-rails-enterprise-dev-swiftgen-integration

SwiftGen Integration — Expert Decisions

Expert decision frameworks for SwiftGen choices. Claude knows asset catalogs and localization — this skill provides judgment calls for when SwiftGen adds value and configuration trade-offs.

Decision Trees

When SwiftGen Adds Value

Should you use SwiftGen for this project? ├─ > 20 assets/strings │ └─ YES — Type safety prevents bugs │ Typos caught at compile time │ ├─ < 10 assets/strings, solo developer │ └─ MAYBE — Overhead vs. benefit │ Quick projects may not need it │ ├─ Team project with shared assets │ └─ YES — Consistency + discoverability │ Autocomplete reveals available assets │ ├─ Assets change frequently │ └─ YES — Broken references caught early │ CI catches missing assets │ └─ CI/CD pipeline exists └─ YES — Validate assets on every build Prevents runtime crashes

The trap: Using SwiftGen on tiny projects or for assets that rarely change. The setup overhead may exceed the benefit.

Template Selection

Which template should you use? ├─ Strings │ ├─ Hierarchical keys (auth.login.title) │ │ └─ structured-swift5 │ │ L10n.Auth.Login.title │ │ │ └─ Flat keys (login_title) │ └─ flat-swift5 │ L10n.loginTitle │ ├─ Assets (Images) │ └─ swift5 (default) │ Asset.Icons.home.image │ ├─ Colors │ └─ swift5 with enumName param │ Asset.Colors.primary.color │ ├─ Fonts │ └─ swift5 │ FontFamily.Roboto.bold.font(size:) │ └─ Storyboards └─ scenes-swift5 StoryboardScene.Main.initialViewController()

Asset Organization Strategy

How should you organize assets? ├─ Small app (< 50 assets) │ └─ Single Assets.xcassets │ Feature folders inside catalog │ ├─ Medium app (50-200 assets) │ └─ Feature-based catalogs │ Auth.xcassets, Dashboard.xcassets │ Multiple swiftgen inputs │ ├─ Large app / multi-module │ └─ Per-module asset catalogs │ Each module owns its assets │ Module-specific SwiftGen runs │ └─ Design system / shared assets └─ Separate DesignSystem.xcassets Shared across targets

Build Phase Strategy

When should SwiftGen run? ├─ Every build │ └─ Run Script phase (before Compile Sources) │ Always current, small overhead │ ├─ Only when assets change │ └─ Input/Output files specified │ Xcode skips if unchanged │ ├─ Manual only (CI generates) │ └─ Commit generated files │ No local SwiftGen needed │ Risk: generated files out of sync │ └─ Pre-commit hook └─ Lint + generate before commit Ensures consistency

NEVER Do

Configuration

NEVER hardcode paths without variables:

❌ Breaks in different environments

strings: inputs: /Users/john/Projects/MyApp/Resources/en.lproj/Localizable.strings outputs: output: /Users/john/Projects/MyApp/Generated/Strings.swift

✅ Use relative paths

strings: inputs: Resources/en.lproj/Localizable.strings outputs: output: Generated/Strings.swift

NEVER forget publicAccess for shared modules:

❌ Generated code is internal — can't use from other modules

xcassets: inputs: Resources/Assets.xcassets outputs: - templateName: swift5 output: Generated/Assets.swift # Missing publicAccess!

✅ Add publicAccess for shared code

xcassets: inputs: Resources/Assets.xcassets outputs: - templateName: swift5 output: Generated/Assets.swift params: publicAccess: true # Accessible from other modules

Generated Code Usage

NEVER use string literals alongside SwiftGen:

// ❌ Defeats the purpose let icon = UIImage(named: "home") // String literal! let title = NSLocalizedString("auth.login.title", comment: "") // String literal!

// ✅ Use generated constants everywhere let icon = Asset.Icons.home.image let title = L10n.Auth.Login.title

NEVER modify generated files:

// ❌ Changes will be overwritten // Generated/Assets.swift enum Asset { enum Icons { static let home = ImageAsset(name: "home")

    // My custom addition  &#x3C;- WILL BE DELETED ON NEXT RUN
    static let customIcon = ImageAsset(name: "custom")
}

}

// ✅ Extend in separate file // Extensions/Asset+Custom.swift extension Asset.Icons { // Extensions survive regeneration }

Build Phase

NEVER put SwiftGen after Compile Sources:

❌ Generated files don't exist when compiling

Build Phases order:

  1. Compile Sources <- Fails: Assets.swift doesn't exist!
  2. Run Script (SwiftGen)

✅ Generate before compiling

Build Phases order:

  1. Run Script (SwiftGen) <- Generates Assets.swift
  2. Compile Sources <- Now Assets.swift exists

NEVER skip SwiftGen availability check:

❌ Build fails if SwiftGen not installed

swiftgen config run # Error: command not found

✅ Check availability, warn instead of fail

if which swiftgen >/dev/null; then swiftgen config run --config "$SRCROOT/swiftgen.yml" else echo "warning: SwiftGen not installed, skipping code generation" fi

Version Control

NEVER commit generated files without good reason:

❌ Merge conflicts, stale files

git add Generated/Assets.swift git add Generated/Strings.swift

✅ Gitignore generated files

.gitignore

Generated/ *.generated.swift

Exception: If CI doesn't run SwiftGen, commit generated files

But then add pre-commit hook to keep them fresh

NEVER leave swiftgen.yml uncommitted:

❌ Team members can't regenerate

.gitignore swiftgen.yml <- WRONG!

✅ Commit configuration

git add swiftgen.yml git add Resources/ # Source assets

String Keys

NEVER use inconsistent key conventions:

❌ Mixed conventions — confusing

"LoginTitle" = "Log In"; "login.button" = "Sign In"; "AUTH_ERROR" = "Error";

✅ Consistent hierarchical keys

"auth.login.title" = "Log In"; "auth.login.button" = "Sign In"; "auth.error.generic" = "Error";

Essential Patterns

Complete swiftgen.yml

swiftgen.yml

Strings (Localization)

strings: inputs: - Resources/en.lproj/Localizable.strings outputs: - templateName: structured-swift5 output: Generated/Strings.swift params: publicAccess: true enumName: L10n

Assets (Images)

xcassets:

  • inputs:
    • Resources/Assets.xcassets outputs:
    • templateName: swift5 output: Generated/Assets.swift params: publicAccess: true

Colors

colors:

  • inputs:
    • Resources/Colors.xcassets outputs:
    • templateName: swift5 output: Generated/Colors.swift params: publicAccess: true enumName: ColorAsset

Fonts

fonts:

  • inputs:
    • Resources/Fonts/ outputs:
    • templateName: swift5 output: Generated/Fonts.swift params: publicAccess: true

SwiftUI Convenience Extensions

// Extensions/SwiftGen+SwiftUI.swift

import SwiftUI

// Image extension extension Image { init(asset: ImageAsset) { self.init(asset.name, bundle: BundleToken.bundle) } }

// Color extension extension Color { init(asset: ColorAsset) { self.init(asset.name, bundle: BundleToken.bundle) } }

// Font extension extension Font { static func custom(_ fontConvertible: FontConvertible, size: CGFloat) -> Font { fontConvertible.swiftUIFont(size: size) } }

// Usage struct ContentView: View { var body: some View { VStack { Image(asset: Asset.Icons.home) .foregroundColor(Color(asset: Asset.Colors.primary))

        Text(L10n.Home.title)
            .font(.custom(FontFamily.Roboto.bold, size: 24))
    }
}

}

Build Phase Script

#!/bin/bash

Xcode Build Phase: Run Script

Move BEFORE "Compile Sources"

set -e

Check if SwiftGen is installed

if ! which swiftgen >/dev/null; then echo "warning: SwiftGen not installed. Install via: brew install swiftgen" exit 0 fi

Navigate to project root

cd "$SRCROOT"

Create output directory if needed

mkdir -p Generated

Run SwiftGen

echo "Running SwiftGen..." swiftgen config run --config swiftgen.yml

echo "SwiftGen completed successfully"

Input Files (for incremental builds):

$(SRCROOT)/swiftgen.yml $(SRCROOT)/Resources/Assets.xcassets $(SRCROOT)/Resources/en.lproj/Localizable.strings $(SRCROOT)/Resources/Colors.xcassets $(SRCROOT)/Resources/Fonts

Output Files:

$(SRCROOT)/Generated/Assets.swift $(SRCROOT)/Generated/Strings.swift $(SRCROOT)/Generated/Colors.swift $(SRCROOT)/Generated/Fonts.swift

Multi-Module Setup

Module: DesignSystem/swiftgen.yml

xcassets:

  • inputs:
    • Sources/DesignSystem/Resources/Colors.xcassets outputs:
    • templateName: swift5 output: Sources/DesignSystem/Generated/Colors.swift params: publicAccess: true # Must be public for cross-module

Module: Feature/swiftgen.yml

strings:

  • inputs:
    • Sources/Feature/Resources/en.lproj/Feature.strings outputs:
    • templateName: structured-swift5 output: Sources/Feature/Generated/Strings.swift params: publicAccess: false # Internal to module enumName: Strings

Quick Reference

Template Options

Asset Type Template Output

Images swift5 Asset.Category.name.image

Colors swift5 Asset.Colors.name.color

Strings structured-swift5 L10n.Category.Subcategory.key

Strings (flat) flat-swift5 L10n.keyName

Fonts swift5 FontFamily.Name.weight.font(size:)

Storyboards scenes-swift5 StoryboardScene.Name.viewController

Common Parameters

Parameter Purpose Example

publicAccess Public access level true for shared modules

enumName Custom enum name L10n, Asset, Colors

allValues Include allValues array true for debugging

preservePath Keep folder structure true for fonts

File Structure

Project/ ├── swiftgen.yml # Configuration (commit) ├── Resources/ │ ├── Assets.xcassets # Images (commit) │ ├── Colors.xcassets # Colors (commit) │ ├── Fonts/ # Custom fonts (commit) │ └── en.lproj/ │ └── Localizable.strings # Strings (commit) └── Generated/ # Output (gitignore) ├── Assets.swift ├── Colors.swift ├── Fonts.swift └── Strings.swift

Troubleshooting

Issue Cause Fix

"No such module" Generated before adding to target Add to target membership

Build fails Run Script after Compile Move before Compile Sources

Stale generated code Missing input/output files Specify all inputs/outputs

Wrong bundle Multi-target project Use correct BundleToken

Red Flags

Smell Problem Fix

String literals for assets Bypasses type safety Use generated constants

Modified generated files Changes get overwritten Use extensions instead

Run Script after Compile Files don't exist Move before Compile Sources

No availability check Build fails without SwiftGen Add which swiftgen check

Committed generated files Merge conflicts, staleness Gitignore, generate on build

Missing publicAccess Can't use across modules Add publicAccess: true

Mixed key conventions Inconsistent L10n structure Use hierarchical keys

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

flutter conventions & best practices

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

getx state management patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

ruby oop patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rails localization (i18n) - english & arabic

No summary provided by upstream source.

Repository SourceNeeds Review