SuperAPI AI Directory

apple-swift

Coding & development

View repository

Updated 10-16 06:45

About this skill

ABOUTME: Apple platform guide, Swift, SwiftUI, concurrency, testing, performance ABOUTME: Conventions, strict concurrency rules, MVVM + DI patterns, review checklists Apple Platform Development

Quick Reference

# Build
xcodebuild -scheme MyApp -sdk iphoneos build
xcodebuild -scheme MyApp -sdk macosx build

# Tests (pick <booted device> from: xcrun simctl list devices | grep Booted)
xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=<booted device>'

# SwiftLint / SPM
swiftlint lint [--fix]
swift build && swift test && swift package resolve
ast-grep

sg --pattern '@Observable final class $NAME { $$$ }' --lang swift sg --pattern '@MainActor' --lang swift


**See also:** `_AST_GREP.md`, `_PATTERNS.md`, `source-control`, `references/`

---

## Version (determine, don't assume)

See `../_LANG_COMMON.md`. Fetch the truth:

```bash
swift --version                                 # local toolchain
xcodebuild -version                             # Xcode version
cat .swift-version 2>/dev/null                  # pinned toolchain (if present)
grep -E 'swift-tools-version' Package.swift     # SPM minimum
curl -s https://api.github.com/repos/swiftlang/swift/releases/latest | jq -r .tag_name  # latest upstream

Pre-Commit Verification (MANDATORY)

make check && make test-e2e must pass (enforced by the pre-commit-gate hook; see ../_LANG_COMMON.md). What make check expands to for an Apple project:

swift build                                     # compilation check
swift test                                      # unit tests
swiftlint lint --strict                         # lint (fail on warnings)
swift-format lint --recursive Sources Tests     # formatting check
xcodebuild -scheme MyApp test \
  -destination 'platform=iOS Simulator,name=<booted device>'   # platform tests

Pick <booted device> from xcrun simctl list devices | grep Booted (do not hardcode a simulator model).


SwiftUI

Property Wrappers

Wrapper Use
@State View-owned values, @Observable
@Binding Two-way to parent
@Bindable Two-way to @Observable props
@Environment System/app values
@StateObject View-owned ObservableObject (legacy)

View property order: @Environment, let, @State/@Binding, computed, init, body, private methods

View sizing: <100 lines = single view; 100-200 = extract subviews; >200 = multiple files; business logic = @Observable VM; network/DB = repository pattern

For NavigationStack, SwiftData, MVVM, and DI patterns, see references/swiftui-patterns.md.


Concurrency

Common Fixes

Error Fix
Main actor isolation Add @MainActor to class/func
Non-isolated access Mark nonisolated
Sendable violation Add @unchecked Sendable or fix
Protocol async Require async in protocol
Closure capture Use @Sendable closure

When to use what

Use Case Choice
One-shot network async/await
Parallel fetches async let / TaskGroup
Real-time streams Combine / AsyncStream
UI events, debounce Combine

NON-NEGOTIABLE: UI updates always on @MainActor. Cross-actor value types must be Sendable. Respect task cancellation: check Task.isCancelled in long-running work.

For MainActor, parallel execution, and actor patterns, see references/concurrency-patterns.md.


Architecture

MVVM with @Observable: @Observable @MainActor final class VM with private(set) properties, injected service protocols, async load methods with defer { isLoading = false }.

DI: Protocol-based with EnvironmentKey for SwiftUI injection.

Coordinator pattern: For flow-heavy apps, lift navigation state out of views into a Coordinator type owning a NavigationPath (or route enum) and exposing intents.

Testing (Swift Testing): @Suite, @Test, #expect. Parameterized with arguments:. Mock via protocol injection. XCTest still valid where needed (UI tests, legacy targets).

For full code examples, see references/swiftui-patterns.md and references/swift6-patterns.md.


Review Checklists

Concurrency: MainActor for UI, Sendable for cross-actor data, task cancellation handled, no data races

SwiftUI: @Observable over ObservableObject where available, NavigationStack over NavigationView, .task over .onAppear + Task, LazyVStack for long lists

CRITICAL: Force unwrap without safety, UI updates off MainActor, data races, retain cycles

HIGH: Legacy ObservableObject when @Observable fits, NavigationView in new code


Detailed References

  • references/swift6-patterns.md - Strict concurrency migration, Sendable, actors, macros
  • references/swiftui-patterns.md - NavigationStack, SwiftData, MVVM, dependency injection
  • references/concurrency-patterns.md - async/await, TaskGroup, MainActor, actors, AsyncStream
  • references/performance.md - Optimization, Instruments profiling, memory management

Official: Swift | SwiftUI | SwiftData

Libraries: TCA | Snapshot Testing | SwiftLint