Skill: ivangdavila/ios (version 1.0.0)

--- name: iOS description: Build, test, and ship iOS apps with Swift, Xcode, and App Store best practices. metadata: {"clawdbot":{"emoji":"📱","requires":{"bins":["xcodebuild"]},"os":["darwin"]}} --- # iOS Development Rules ## Xcode & Build - Clean build folder (Cmd+Shift+K) fixes most "impossible" build errors — derived data gets corrupted regularly - Simulator reset (Device > Erase All Content and Settings) clears cached app state that survives reinstalls - Archive builds use Release config — bugs that only appear in production often stem from optimization differences - `xcodebuild -showsdks` lists available SDKs — useful when builds fail with "SDK not found" - Parallel builds can cause race conditions in script phases — add input/output file lists to enforce ordering ## Code Signing - "No signing certificate" usually means certificate is expired or revoked — check in Keychain Access, not just Xcode - Provisioning profiles embed device UDIDs — new test device requires profile regeneration and reinstall - Automatic signing fails in CI — always use manual signing with exported credentials for builds - Distribution certificates are limited to 3 per account — don't create new ones, export and share the existing one - After renewing a certificate, update ALL provisioning profiles that used the old one ## SwiftUI Patterns - `@State` for view-local data, `@StateObject` for owned ObservableObjects, `@ObservedObject` for passed-in objects — mixing them wrong causes crashes or lost state - `List` with `id: \.self` on non-Hashable types causes silent failures — always use explicit `id` parameter with stable identifiers - `task` modifier cancels automatically on view disappear — no manual cancellation needed, but check `Task.isCancelled` in loops - Previews crash silently with real network calls — use mock data or dependency injection for previews - `@Environment` values are nil in previews unless explicitly provided — wrap previews in container with environment set ## App Store Rules - Apps must work offline or show clear offline state — silent failures cause rejection - Login must be skippable if app has non-account features — reviewers reject mandatory login for content browsing - "Sign in with Apple" is required if you offer any third-party social login — no exceptions - Privacy labels must match actual data collection — Apple verifies and rejects mismatches - In-app purchases must use StoreKit for digital goods — external payment links get rejected ## Info.plist Requirements - `ITSAppUsesNonExemptEncryption = NO` avoids export compliance questions for most apps — add it to skip the daily annoyance - Camera/microphone/location usage descriptions are mandatory — missing them crashes the app on access attempt - `LSApplicationQueriesSchemes` must list URL schemes before `canOpenURL` works — iOS 9+ security requirement - `UIRequiresFullScreen = YES` on iPad opts out of multitasking — use only if your app truly can't support split view ## Performance - `Instruments > Time Profiler` reveals actual bottlenecks — don't guess, measure - Images in Assets.xcassets get optimized automatically — loose files in bundle don't - `@MainActor` annotation ensures UI updates happen on main thread — missing it causes random crashes under load - Memory leaks often hide in closures — use `[weak self]` in escaping closures that reference `self` - `List` with thousands of items is fast, `ForEach` in `ScrollView` is not — List uses cell reuse, ScrollView loads everything ## Debugging - `po` in LLDB prints object description, `p` prints raw value — use `po` for most debugging - Purple warnings in Console indicate main thread violations — fix these, they cause jank - `-com.apple.CoreData.SQLDebug 1` in launch arguments shows all Core Data queries — essential for debugging fetch performance - Crash logs without symbols are useless — keep dSYM files for every release build - TestFlight crashes appear in Xcode Organizer — check there, not just in App Store Connect


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)