XcodeGen iOS workflow
Quick start
- Treat
project.yml(orproject.yaml) as the source of truth; regenerate withxcodegen generatebefore building. - Do not edit the generated
.xcodeprojdirectly; delete and regenerate as needed.
Build / Run
- For “Designed for iPad on Mac” builds, use a macOS destination with
variant=Designed for iPadwhen available. - For tests, prefer an iOS Simulator if any vendor frameworks lack Mac Catalyst support.
Tests
- Ensure the test target is added to the scheme and has a host app if required.
- If tests show 0 cases, recheck the scheme and any test plan configuration.
- If
@testable importfails, confirm the host app module name and that tests build for the same destination as the host.
Resources / Assets
- Asset catalogs and storyboards must be in the resources build phase. In XcodeGen, add them under
sourceswithbuildPhase: resources. - Enable asset symbol generation when code uses generated
ColorAsset/ImageAssetsymbols:ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOLS=YESASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS=YES
SwiftPM in CI
- If CI disables automatic dependency resolution, ensure
Package.resolvedis committed or copied to the expected location (usually.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved) before build. - Keep versions pinned in
project.ymlwhen deterministic builds are required.
App Store Connect packaging issues
- Static
.afiles must never appear under*.app/Frameworks. - XcodeGen does not support a
library:dependency key; to link a.afile, use:framework: path/to/libSomething.aembed: false
- XCFrameworks that contain static libs should also be linked only:
- set
embed: falsefor those XCFrameworks to avoid.aslices being copied intoFrameworks/.
- set
- Verify the generated project’s “Embed Frameworks” build phase contains only dynamic frameworks that must be embedded.
Diagnostics / sanity checks
- Regenerate and clean Derived Data after changing
project.yml. - After archiving, inspect the app bundle’s
Frameworks/directory; it should contain only dynamic frameworks and Swift runtime libraries.