
developing-ios-apps
Builds and ships iOS/macOS apps with XcodeGen, SwiftUI and SPM: Xcode build fixes, device deployment, Apple Developer signing/notarization, CI/CD pipelines. Use for XcodeGen project.yml setup, "Library not loaded @rpath" crashes, code-signing errors (Error -25294, adhoc fallback), or Electron notarization failures. Not for TCC permission dialogs (use macos-permissions) or disk cleanup (use macos-cleaner).
- Installs
- 1.5K
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/daymade/claude-code-skills --skill developing-ios-apps- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads developing-ios-apps automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
iOS App Development
Build, configure, and deploy iOS applications using XcodeGen and Swift Package Manager.
Critical Warnings
| Issue | Cause | Solution |
|---|---|---|
| "Library not loaded: @rpath/Framework" | XcodeGen doesn't auto-embed SPM dynamic frameworks | Build in Xcode GUI first (not xcodebuild). See Troubleshooting |
xcodegen generate loses signing | Overwrites project settings | Configure in project.yml target settings, not global |
| Command-line signing fails | Free Apple ID limitation | Use Xcode GUI or paid developer account ($99/yr) |
| "Cannot be set when automaticallyAdjustsVideoMirroring is YES" | Setting isVideoMirrored without disabling automatic | Set automaticallyAdjustsVideoMirroring = false first. See Camera |
| App signed as adhoc despite certificate | @electron/packager defaults continueOnError: true | Set continueOnError: false in osxSign. See Code Signing |
| "Cannot use password credentials, API key credentials..." | Passing teamId to @electron/notarize with API key auth | Remove teamId. notarytool infers team from API key. See Code Signing |
| EMFILE during signing (large embedded runtime) | @electron/osx-sign traverses all files in .app bundle | Add ignore filter + ulimit -n 65536 in CI. See Code Signing |
Quick Reference
| Task | Command |
|---|---|
| Generate project | xcodegen generate |
| Build simulator | xcodebuild -destination 'platform=iOS Simulator,name=iPhone 17' build |
| Build device (paid account) | xcodebuild -destination 'platform=iOS,name=DEVICE' -allowProvisioningUpdates build |
| Clean DerivedData | rm -rf ~/Library/Developer/Xcode/DerivedData/PROJECT-* |
| Find device name | xcrun xctrace list devices |
XcodeGen Configuration
Minimal project.yml
name: AppName
options:
bundleIdPrefix: com.company
deploymentTarget:
iOS: "16.0"
settings:
base:
SWIFT_VERSION: "6.0"
packages:
SomePackage:
url: https://github.com/org/repo
from: "1.0.0"
targets:
AppName:
type: application
platform: iOS
sources:
- path: AppName
settings:
base:
INFOPLIST_FILE: AppName/Info.plist
PRODUCT_BUNDLE_IDENTIFIER: com.company.appname
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: TEAM_ID_HERE
dependencies:
- package: SomePackage
Code Signing Configuration
Personal (free) account: Works in Xcode GUI only. Command-line builds require paid account.
# In target settings
settings:
base:
CODE_SIGN_STYLE: Automatic
DEVELOPMENT_TEAM: TEAM_ID # Get from Xcode → Settings → Accounts
Get Team ID:
security find-identity -v -p codesigning | head -3
iOS Version Compatibility
API Changes by Version
| iOS 17+ Only | iOS 16 Compatible |
|---|---|
.onChange { old, new in } | .onChange { new in } |
ContentUnavailableView | Custom VStack |
AVAudioApplication | AVAudioSession |
@Observable macro | @ObservableObject |
| SwiftData | CoreData/Realm |
Lowering Deployment Target
- Update
project.yml:
deploymentTarget:
iOS: "16.0"
- Fix incompatible APIs:
// iOS 17
.onChange(of: value) { oldValue, newValue in }
// iOS 16
.onChange(of: value) { newValue in }
// iOS 17
ContentUnavailableView("Title", systemImage: "icon")
// iOS 16
VStack {
Image(systemName: "icon").font(.system(size: 48))
Text("Title").font(.title2.bold())
}
// iOS 17
AVAudioApplication.shared.recordPermission
// iOS 16
AVAudioSession.sharedInstance().recordPermission
- Regenerate:
xcodegen generate
Device Deployment
First-time Setup
- Connect device via USB
- Trust computer on device
- In Xcode: Settings → Accounts → Add Apple ID
- Select device in scheme dropdown
- Run (
Cmd + R) - On device: Settings → General → VPN & Device Management → Trust
Command-line Build (requires paid account)
xcodebuild \
-project App.xcodeproj \
-scheme App \
-destination 'platform=iOS,name=DeviceName' \
-allowProvisioningUpdates \
build
Common Issues
| Error | Solution |
|---|---|
| "Library not loaded: @rpath/Framework" | SPM dynamic framework not embedded. Build in Xcode GUI first, then CLI works |
| "No Account for Team" | Add Apple ID in Xcode Settings → Accounts |
| "Provisioning profile not found" | Free account limitation. Use Xcode GUI or get paid account |
| Device not listed | Reconnect USB, trust computer on device, restart Xcode |
| DerivedData won't delete | Close Xcode first: pkill -9 Xcode && rm -rf ~/Library/Developer/Xcode/DerivedData/PROJECT-* |
Free vs Paid Developer Account
| Feature | Free Apple ID | Paid ($99/year) |
|---|---|---|
| Xcode GUI builds | ✅ | ✅ |
| Command-line builds | ❌ | ✅ |
| App validity | 7 days | 1 year |
| App Store | ❌ | ✅ |
| CI/CD | ❌ | ✅ |
SPM Dependencies
SPM Dynamic Framework Not Embedded
Root Cause: XcodeGen doesn't generate the "Embed Frameworks" build phase for SPM dynamic frameworks (like RealmSwift, Realm). The app builds successfully but crashes on launch with:
dyld: Library not loaded: @rpath/RealmSwift.framework/RealmSwift
Referenced from: /var/containers/Bundle/Application/.../App.app/App
Reason: image not found
Why This Happens:
- Static frameworks (most SPM packages) are linked into the binary - no embedding needed
- Dynamic frameworks (RealmSwift, etc.) must be copied into the app bundle
- XcodeGen generates link phase but NOT embed phase for SPM packages
embed: truein project.yml causes build errors (XcodeGen limitation)
The Fix (Manual, one-time per project):
- Open project in Xcode GUI
- Select target → General → Frameworks, Libraries
- Find the dynamic framework (RealmSwift)
- Change "Do Not Embed" → "Embed & Sign"
- Build and run from Xcode GUI first
After Manual Fix: Command-line builds (xcodebuild) will work because Xcode persists the embed setting in project.pbxproj.
Identifying Dynamic Frameworks:
# Check if a framework is dynamic
file ~/Library/Developer/Xcode/DerivedData/PROJECT-*/Build/Products/Debug-iphoneos/FRAMEWORK.framework/FRAMEWORK
# Dynamic: "Mach-O 64-bit dynamically linked shared library"
# Static: "current ar archive"
Adding Packages
packages:
AudioKit:
url: https://github.com/AudioKit/AudioKit
from: "5.6.5"
RealmSwift:
url: https://github.com/realm/realm-swift
from: "10.54.6"
targets:
App:
dependencies:
- package: AudioKit
- package: RealmSwift
product: RealmSwift # Explicit product name when package has multiple
Resolving Dependencies (China proxy)
git config --global http.proxy http://127.0.0.1:1082
git config --global https.proxy http://127.0.0.1:1082
xcodebuild -scmProvider system -resolvePackageDependencies
Never clear global SPM cache (~/Library/Caches/org.swift.swiftpm). Re-downloading is slow.
Camera / AVFoundation
Camera preview requires real device (simulator has no camera).
Quick Debugging Checklist
- Permission: Added
NSCameraUsageDescriptionto Info.plist? - Device: Running on real device, not simulator?
- Session running:
session.startRunning()called on background thread? - View size: UIViewRepresentable has non-zero bounds?
- Video mirroring: Disabled
automaticallyAdjustsVideoMirroringbefore settingisVideoMirrored?
Video Mirroring (Front Camera)
CRITICAL: Must disable automatic adjustment before setting manual mirroring:
// WRONG - crashes with "Cannot be set when automaticallyAdjustsVideoMirroring is YES"
connection.isVideoMirrored = true
// CORRECT - disable automatic first
connection.automaticallyAdjustsVideoMirroring = false
connection.isVideoMirrored = true
UIViewRepresentable Sizing Issue
UIViewRepresentable in ZStack may have zero bounds. Fix with explicit frame:
// BAD: UIViewRepresentable may get zero size in ZStack
ZStack {
CameraPreviewView(session: session) // May be invisible!
OtherContent()
}
// GOOD: Explicit sizing
ZStack {
GeometryReader { geo in
CameraPreviewView(session: session)
.frame(width: geo.size.width, height: geo.size.height)
}
.ignoresSafeArea()
OtherContent()
}
Debug Logging Pattern
Add logging to trace camera flow:
import os
private let logger = Logger(subsystem: "com.app", category: "Camera")
func start() async {
logger.info("start() called, isRunning=\(self.isRunning)")
// ... setup code ...
logger.info("session.startRunning() completed")
}
// For CGRect (doesn't conform to CustomStringConvertible)
logger.info("bounds=\(NSCoder.string(for: self.bounds))")
Filter in Console.app by subsystem.
For detailed camera implementation: See references/camera-avfoundation.md
macOS Code Signing & Notarization
For distributing macOS apps (Electron or native) outside the App Store, signing + notarization is required. Without it users see "Apple cannot check this app for malicious software."
5-step checklist:
| Step | What | Critical detail |
|---|---|---|
| 1 | Create CSR in Keychain Access | Common Name doesn't matter; choose "Saved to disk" |
| 2 | Request Developer ID Application cert at developer.apple.com | Choose G2 Sub-CA (not Previous Sub-CA) |
| 3 | Install .cer → must choose login keychain | iCloud/System → Error -25294 (private key mismatch) |
| 4 | Export P12 from login keychain with password | Base64: base64 -i cert.p12 | pbcopy |
| 5 | Create App Store Connect API Key (Developer role) | Download .p8 once only; record Key ID + Issuer ID |
GitHub Secrets required (5 secrets):
| Secret | Source |
|---|---|
MACOS_CERT_P12 | Step 4 base64 |
MACOS_CERT_PASSWORD | Step 4 password |
APPLE_API_KEY | Step 5 .p8 base64 |
APPLE_API_KEY_ID | Step 5 Key ID |
APPLE_API_ISSUER | Step 5 Issuer ID |
APPLE_TEAM_IDis NOT needed.notarytoolinfers team from the API key. PassingteamIdto@electron/notarizev2.5.0 causes a credential conflict error.
Electron Forge osxSign critical settings:
osxSign: {
identity: 'Developer ID Application',
hardenedRuntime: true,
entitlements: 'entitlements.mac.plist',
entitlementsInherit: 'entitlements.mac.plist',
continueOnError: false, // CRITICAL: default is true, silently falls back to adhoc
// Skip non-binary files in large embedded runtimes (prevents EMFILE)
ignore: (filePath: string) => {
if (!filePath.includes('python-runtime')) return false;
if (/\.(so|dylib|node)$/.test(filePath)) return false;
return true;
},
// CI: explicitly specify keychain (apple-actions/import-codesign-certs uses signing_temp.keychain)
...(process.env.MACOS_SIGNING_KEYCHAIN
? { keychain: process.env.MACOS_SIGNING_KEYCHAIN }
: {}),
},
Fail-fast three-layer defense:
@electron/osx-sign:continueOnError: false— signing error throws immediatelypostPackagehook:codesign --verify --deep --strict+ adhoc detection- Release trigger script: verify local HEAD matches remote before dispatch
Verify signing:
security find-identity -v -p codesigning | grep "Developer ID Application"
For complete step-by-step guide, entitlements, workflow examples, and full troubleshooting (7 real-world errors with root causes): references/apple-codesign-notarize.md
Resources
- references/xcodegen-full.md - Complete project.yml options
- references/swiftui-compatibility.md - iOS version API differences
- references/camera-avfoundation.md - Camera preview debugging
- references/testing-mainactor.md - Testing @MainActor classes (state machines, regression tests)
- references/apple-codesign-notarize.md - Apple Developer signing + notarization for macOS/Electron CI/CD
FAQ
What does the developing-ios-apps skill do?
Builds and ships iOS/macOS apps with XcodeGen, SwiftUI and SPM: Xcode build fixes, device deployment, Apple Developer signing/notarization, CI/CD pipelines. Use for XcodeGen project.yml setup, "Library not loaded @rpath" crashes, code-signing errors (Error -25294, adhoc fallback), or Electron notarization failures. Not for TCC permission dialogs (use macos-permissions) or disk cleanup (use macos-cleaner).
How do I install developing-ios-apps?
Run npx skills add https://github.com/daymade/claude-code-skills --skill developing-ios-apps in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/developing-ios-apps/ (personal) or .claude/skills/developing-ios-apps/ (project).
Which AI agents can use developing-ios-apps?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is developing-ios-apps safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains developing-ios-apps?
It is published by daymade in daymade/claude-code-skills. It has 1,514 recorded installs.
More from daymade/claude-code-skills
twitter-reader
daymade/claude-code-skills
Fetches Twitter/X post and Article content — text, author, engagement metrics and embedded media — downloading images locally and generating complete Markdown with image references. Use when retrieving a tweet's text or an X Article with images, or pulling post metadata for a Markdown/PKM record. Preferred over Jina alone for X Articles with images.
i18n-expert
daymade/claude-code-skills
This skill should be used when setting up, auditing, or enforcing internationalization/localization in UI codebases (React/TS, i18next or similar, JSON locales), including installing/configuring the i18n framework, replacing hard-coded strings, ensuring en-US/zh-CN coverage, mapping error codes to localized messages, and validating key parity, pluralization, and formatting.
prompt-optimizer
daymade/claude-code-skills
Transforms vague prompts or feature requests into precise, testable specifications using EARS (Easy Approach to Requirements Syntax) grounded in relevant domain theories (GTD, BJ Fogg, Gestalt). Use when requirements lack triggers or measurable outcomes, or the user asks to "optimize my prompt" / "improve this requirement" / "make this more specific".
ppt-creator
daymade/claude-code-skills
Deprecated presentation entry retained as a compatibility notice. Use to check the retirement status of ppt-creator or identify a legacy installation. This package does not generate PPTX files.
qa-expert
daymade/claude-code-skills
Sets up QA testing processes: test strategies, Google Testing Standards test cases, P0-P4 bug tracking, quality metrics, progress reports, autonomous execution via master prompts, and OWASP security testing, with third-party QA handoff docs. Use when establishing QA infrastructure, writing test cases, executing test plans, or tracking bugs. Not for auditing an already-rendered UI (use frontend-visual-qa).
macos-cleaner
daymade/claude-code-skills
Diagnoses and safely reclaims macOS disk space: caches, logs, app remnants, large/duplicate files, Docker/OrbStack, Chromium code-sign clones, developer caches. Use when a Mac is low on storage, shows “Caching needs more space”, or before deleting anything to avoid data loss. Not for Windows/Linux or permission issues (use macos-permissions).
Popular mobile skills
design-mobile-apps
designed-by-ai/skills
Design mobile app screens with Sleek, edit Sleek projects, and implement their designs in React Native or HTML.
ios-design
uizze.sh
Design and review iOS UI/UX for iPhone apps in SwiftUI, UIKit, or React Native. Use for mobile app design, screen redesigns, navigation flows, typography, forms, keyboard and safe-area layout, and accessibility checks. Apply Apple Human Interface Guidelines and consult real product references through the optional Uizze connection.
vercel-react-native-skills
vercel-labs/agent-skills
React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.
animate-expo
emilkowalski/skills
Build animations in React Native and Expo, making the decisions in the order that determines whether they feel right — should it animate, which thread it runs on, which properties, spring or timing, how the gesture hands off, how it degrades. Writes the implementation with Reanimated, Gesture Handler, Expo Router and expo-haptics. Use when animating anything in an Expo app, adding gestures, sheets, screen transitions, press feedback or haptics, or fixing motion that stutters on device. For web animation use animate.
xcode-project-setup
firebase/agent-skills
Safely modifies Xcode projects (.pbxproj) to add Swift Packages and link files. Use this skill whenever an iOS project needs dependencies installed (e.g. Firebase, Alamofire).
firebase-remote-config-basics
firebase/agent-skills
Manages Firebase Remote Config templates, feature flags, loading strategies, and SDKs (Android, iOS). Use when downloading/deploying remoteconfig JSON templates, managing version history/feature flags, setting in-app defaults, fetchAndActivate(), real-time listeners, or SDK setup. Don't use for Firebase Hosting, Auth, Firestore, Data Connect, Crashlytics, or App Hosting.