Ios build config
Skill almasumdev/awesome-ios-agent-skills/.github/skills/build_and_tooling/ios-build-config
Curated agent skills, conventions, and workflows for building iOS apps (Swift, SwiftUI, UIKit) with AI coding agents.
npx -y skills add almasumdev/awesome-ios-agent-skills --skill ios-build-configAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Expert guidance on Xcode build configuration — schemes, xcconfig files, SPM package graph, build settings hygiene, and secret handling. Use when setting up or cleaning build settings.
SKILL.md
6.0 KB, as published. Nobody here has run it
iOS Build Configuration
Instructions
The build system is the foundation for reliable CI, reproducible releases, and painless onboarding. Keep settings in files, not in the Xcode project GUI, and model environments as configurations, not branches.
1. Schemes vs Configurations vs Targets
| Concept | Purpose |
|---|---|
| Configuration | Debug / Release / Staging; selects .xcconfig |
| Scheme | Launches with a chosen configuration and args |
| Target | Produces a binary (app, framework, extension, tests) |
Typical layout: one app target, one framework target per SPM package (when using Xcode projects), a Debug and Release configuration per environment (Debug-Dev, Debug-Prod, Release-Prod).
2. xcconfig Files
Put every build setting into an .xcconfig file. This keeps diffs readable and avoids GUI-drift.
// Config/Shared.xcconfig
IPHONEOS_DEPLOYMENT_TARGET = 15.0
SWIFT_VERSION = 5.10
SWIFT_STRICT_CONCURRENCY = complete
ENABLE_USER_SCRIPT_SANDBOXING = YES
ENABLE_MODULE_VERIFIER = YES
OTHER_SWIFT_FLAGS = $(inherited) -enable-experimental-feature StrictConcurrency
// Config/Debug.xcconfig
#include "Shared.xcconfig"
SWIFT_OPTIMIZATION_LEVEL = -Onone
SWIFT_COMPILATION_MODE = singlefile
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) DEBUG=1
OTHER_SWIFT_FLAGS = $(inherited) -DDEBUG
// Config/Release.xcconfig
#include "Shared.xcconfig"
SWIFT_OPTIMIZATION_LEVEL = -O
SWIFT_COMPILATION_MODE = wholemodule
VALIDATE_PRODUCT = YES
Wire them via Project → Info → Configurations.
3. Environments as Configurations
Prefer configurations over build flags for environment switching. Debug-Prod vs Debug-Dev pick different API_BASE_URL, bundle id suffixes, and entitlements.
// Config/Dev.xcconfig
PRODUCT_BUNDLE_IDENTIFIER = com.example.MyApp.dev
API_BASE_URL = https:/$()/api.dev.example.com
ASSET_CATALOG_APP_ICON_NAME = AppIconDev
(Note: xcconfig treats // as a comment. Escape URLs with $().)
Consume in Swift via Info.plist keys:
<key>API_BASE_URL</key>
<string>$(API_BASE_URL)</string>
enum Env {
static let apiBaseURL = URL(string: Bundle.main.object(forInfoDictionaryKey: "API_BASE_URL") as! String)!
}
4. SPM Package Graph
Model features as SPM packages. Keep the root manifest small, and pin versions with .exact or ranges — never .branch for release builds.
// Package.swift (feature package)
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "Articles",
platforms: [.iOS(.v15)],
products: [
.library(name: "ArticlesUI", type: .static, targets: ["ArticlesUI"]),
],
dependencies: [
.package(url: "https://github.com/pointfreeco/swift-snapshot-testing", from: "1.17.0"),
],
targets: [
.target(name: "ArticlesDomain"),
.target(name: "ArticlesData", dependencies: ["ArticlesDomain"]),
.target(name: "ArticlesUI", dependencies: ["ArticlesDomain"]),
.testTarget(name: "ArticlesDomainTests", dependencies: ["ArticlesDomain"]),
]
)
Static libraries reduce dynamic-framework launch cost — see the ios-app-launch skill.
5. Build Settings Hygiene
- Swift:
SWIFT_STRICT_CONCURRENCY = completefor Swift 6 readiness. - Warnings as errors:
SWIFT_TREAT_WARNINGS_AS_ERRORS = YESfor libraries; gate app target by CI. - Bitcode: deprecated — leave off.
- Dead code:
DEAD_CODE_STRIPPING = YES,STRIP_SWIFT_SYMBOLS = YESon Release. - Module verifier:
ENABLE_MODULE_VERIFIER = YESto catch header issues early. - User script sandboxing:
ENABLE_USER_SCRIPT_SANDBOXING = YES(Xcode 15+). - Debug info:
DEBUG_INFORMATION_FORMAT = dwarf-with-dsymon Release for symbolicated crash reports.
6. Signing
- Use Automatic signing for dev; Manual with a shared certificate + provisioning profiles for CI.
- Check profiles into a private repo via
fastlane match. - Set
DEVELOPMENT_TEAMin anxcconfig, not in the project file.
7. Secrets
Never commit API keys. Options:
- xcconfig with git-ignored overlay:
Config/Secrets.xcconfig(gitignored) with#include? "Secrets.xcconfig"inShared.xcconfig. - CI environment variables injected at build time into an
xcconfig. - Key rotation-friendly storage: fetch short-lived tokens at runtime, not at build time, for anything that can be rotated quickly.
8. Product Settings
MARKETING_VERSION(user-facing) andCURRENT_PROJECT_VERSION(build number) belong inxcconfig. CI bumps the build number.ASSET_CATALOG_APP_ICON_NAMEvaries per environment so dev builds are visually distinct on-device.INFOPLIST_KEY_*settings (Xcode 13+) keepInfo.plistgenerated, not maintained by hand.
9. Pre-build Phases
Keep "Run Script" phases minimal and fast. Prefer SPM plugins or build tools for codegen. Every script phase increases incremental build time.
10. Reproducibility
- Pin the Xcode version in a
.xcode-versionfile. - Lock SPM dependencies via
Package.resolvedcommitted to the repo. - Fail CI if
Package.resolvedchanges unexpectedly.
Checklist
- All build settings live in
.xcconfigfiles, not the GUI. - Environments are configurations with separate
xcconfigs. -
SWIFT_STRICT_CONCURRENCY = completeon new modules. -
DEBUG_INFORMATION_FORMAT = dwarf-with-dsymon Release. - Signing identities and profiles are managed via
matchor equivalent. - No secrets in the repo; secrets injected via ignored xcconfig or CI env.
-
Package.resolvedcommitted;.xcode-versionpinned.