DE

developing-ios-apps

Manages iOS and macOS development, including build configurations, signing, and CI/CD pipelines.

Install

mkdir -p .claude/skills/developing-ios-apps && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/5646" && unzip -o skill.zip -d .claude/skills/developing-ios-apps && rm skill.zip

Installs to .claude/skills/developing-ios-apps

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Develops iOS/macOS apps with XcodeGen, SwiftUI, and SPM, including Apple Developer signing, notarization, and CI/CD pipelines. Use when building iOS/macOS apps, fixing Xcode build failures, deploying to real devices, or configuring CI/CD signing. Triggers on XcodeGen project.yml, SPM dependency issues, code signing errors (Error -25294, keychain mismatch, adhoc fallback, EMFILE, notarization credential conflict), "Library not loaded @rpath", Electron @electron/osx-sign / @electron/notarize, notarytool, or certificate/provisioning problems.
545 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Generates Xcode project structure via XcodeGen
  • Manages SPM dynamic framework linking
  • Configures notarization and code signing parameters
  • Debugs AVFoundation mirror settings
  • Applies ulimit adjustments to prevent EMFILE errors

How it works

Applies a set of manual configuration overrides and build checklist protocols to common XcodeGen and CI/CD signing failure patterns.

Inputs & outputs

You give it
XcodeGen project.yml configuration
You get back
Ready-to-build Xcode workspace or signed application bundle

When to use developing-ios-apps

  • Resolving library loading errors
  • Configuring code signing for distribution
  • Setting up project.yml for XcodeGen

About this skill

iOS App Development

Build, configure, and deploy iOS applications using XcodeGen and Swift Package Manager.

Critical Warnings

IssueCauseSolution
"Library not loaded: @rpath/Framework"XcodeGen doesn't auto-embed SPM dynamic frameworksBuild in Xcode GUI first (not xcodebuild). See Troubleshooting
xcodegen generate loses signingOverwrites project settingsConfigure in project.yml target settings, not global
Command-line signing failsFree Apple ID limitationUse Xcode GUI or paid developer account ($99/yr)
"Cannot be set when automaticallyAdjustsVideoMirroring is YES"Setting isVideoMirrored without disabling automaticSet automaticallyAdjustsVideoMirroring = false first. See Camera
App signed as adhoc despite certificate@electron/packager defaults continueOnError: trueSet continueOnError: false in osxSign. See Code Signing
"Cannot use password credentials, API key credentials..."Passing teamId to @electron/notarize with API key authRemove teamId. notarytool infers team from API key. See Code Signing
EMFILE during signing (large embedded runtime)@electron/osx-sign traverses all files in .app bundleAdd ignore filter + ulimit -n 65536 in CI. See Code Signing

Quick Reference

TaskCommand
Generate projectxcodegen generate
Build simulatorxcodebuild -destination 'platform=iOS Simulator,name=iPhone 17' build
Build device (paid account)xcodebuild -destination 'platform=iOS,name=DEVICE' -allowProvisioningUpdates build
Clean DerivedDatarm -rf ~/Library/Developer/Xcode/DerivedData/PROJECT-*
Find device namexcrun 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+ OnlyiOS 16 Compatible
.onChange { old, new in }.onChange { new in }
ContentUnavailableViewCustom VStack
AVAudioApplicationAVAudioSession
@Observable macro@ObservableObject
SwiftDataCoreData/Realm

Lowering Deployment Target

  1. Update project.yml:
deploymentTarget:
  iOS: "16.0"
  1. 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
  1. Regenerate: xcodegen generate

Device Deployment

First-time Setup

  1. Connect device via USB
  2. Trust computer on device
  3. In Xcode: Settings → Accounts → Add Apple ID
  4. Select device in scheme dropdown
  5. Run (Cmd + R)
  6. 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

ErrorSolution
"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 listedReconnect USB, trust computer on device, restart Xcode
DerivedData won't deleteClose Xcode first: pkill -9 Xcode && rm -rf ~/Library/Developer/Xcode/DerivedData/PROJECT-*

Free vs Paid Developer Account

FeatureFree Apple IDPaid ($99/year)
Xcode GUI builds
Command-line builds
App validity7 days1 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: true in project.yml causes build errors (XcodeGen limitation)

The Fix (Manual, one-time per project):

  1. Open project in Xcode GUI
  2. Select target → General → Frameworks, Libraries
  3. Find the dynamic framework (RealmSwift)
  4. Change "Do Not Embed" → "Embed & Sign"
  5. 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

  1. Permission: Added NSCameraUsageDescription to Info.plist?
  2. Device: Running on real device, not simulator?
  3. Session running: session.startRunning() called on background thread?
  4. View size: UIViewRepresentable has non-zero bounds?
  5. Video mirroring: Disabled automaticallyAdjustsVideoMirroring before setting isVideoMirrored?

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:

StepWhatCritical detail
1Create CSR in Keychain AccessCommon Name doesn't matter; choose "Saved to disk"
2Request Developer ID Application cert at developer.apple.comChoose G2 Sub-CA (not Previous Sub-CA)
3Install .cer → must choose login keychainiCloud/System → Error -25294 (private key mismatch)
4Export P12 from login keychain with passwordBase64: base64 -i cert.p12 | pbcopy
5Create App Store Connect API Key (Developer role)Downloa

Content truncated.

When not to use it

  • Non-Swift/non-Apple ecosystem projects
  • Simple single-file iOS scripts

Prerequisites

xcodeXcodeGenApple Developer account

Limitations

  • XcodeGen can overwrite manual project settings
  • Free Apple IDs have limitations on automated signing

How it compares

Automates specific edge-case fixes for XcodeGen/SPM conflicts that usually require manual trial-and-error in the GUI.

Compared to similar skills

developing-ios-apps side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
developing-ios-apps (this skill)12moReviewIntermediate
build-macos-apps708moReviewIntermediate
ios-developer104moNo flagsAdvanced
xcodebuildmcp243moNo flagsAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

ppt-creator

daymade

Create professional slide decks from topics or documents. Generates structured content with data-driven charts, speaker notes, and complete PPTX files. Applies persuasive storytelling principles (Pyramid Principle, assertion-evidence). Supports multiple formats (Marp, PowerPoint). Use for presentations, pitches, slide decks, or keynotes.

75110

macos-cleaner

daymade

Analyze and reclaim macOS disk space through intelligent cleanup recommendations. This skill should be used when users report disk space issues, need to clean up their Mac, or want to understand what's consuming storage. Focus on safe, interactive analysis with user confirmation before any deletions.

1631

qa-expert

daymade

This skill should be used when establishing comprehensive QA testing processes for any software project. Use when creating test strategies, writing test cases following Google Testing Standards, executing test plans, tracking bugs with P0-P4 classification, calculating quality metrics, or generating progress reports. Includes autonomous execution capability via master prompts and complete documentation templates for third-party QA team handoffs. Implements OWASP security testing and achieves 90% coverage targets.

1427

repomix-unmixer

daymade

Extracts files from repomix-packed repositories, restoring original directory structures from XML/Markdown/JSON formats. Activates when users need to unmix repomix files, extract packed repositories, restore file structures from repomix output, or reverse the repomix packing process.

524

teams-channel-post-writer

daymade

Creates educational Teams channel posts for internal knowledge sharing about Claude Code features, tools, and best practices. Applies when writing posts, announcements, or documentation to teach colleagues effective Claude Code usage, announce new features, share productivity tips, or document lessons learned. Provides templates, writing guidelines, and structured approaches emphasizing concrete examples, underlying principles, and connections to best practices like context engineering. Activates for content involving Teams posts, channel announcements, feature documentation, or tip sharing.

591

twitter-reader

daymade

Fetch Twitter/X post content by URL using jina.ai API to bypass JavaScript restrictions. Use when Claude needs to retrieve tweet content including author, timestamp, post text, images, and thread replies. Supports individual posts or batch fetching from x.com or twitter.com URLs.

552

Search skills

Search the agent skills registry