swift

Write Swift with optionals, value types, protocols, async/await, and actors; manage state in SwiftUI workflows.

SKILL.md

GitHub

Swift Language AI Skill Guide

Overview & Engine Architecture

Swift emphasizes safe value semantics (struct/enum), optionals instead of null, and structured concurrency (async/await, Task, actor). Agents prefer value types for models, isolate mutable shared state in actors, avoid force-unwraps, and keep SwiftUI views thin by moving logic into models/observables.

Task / async call
      |
  await suspension
      |
  actor-isolated state (optional)
      |
  UI update on MainActor

When to use this skill

  • Writing iOS/macOS application logic in Swift
  • Adopting async/await over completion handlers
  • Designing protocols and generics idiomatically
  • Fixing data races and main-thread UI violations

Operational directives

  1. Prefer struct + Codable for models; use class when identity/sharing is required.
  2. Mark UI-facing models @MainActor when they publish to SwiftUI.
  3. Use async throws APIs; map errors at the boundary for user display.
  4. Avoid ! force unwraps; use guard let / if let / nil-coalescing deliberately.
  5. Sendable-check shared concurrent data; use actors for mutable isolation.

Async sketch

struct Item: Identifiable, Codable, Sendable {
  let id: String
  let sku: String
  let qty: Int
}

enum ItemsError: Error {
  case invalidResponse
}

actor ItemStore {
  private var cache: [Item] = []

  func load(from url: URL) async throws -> [Item] {
    let (data, response) = try await URLSession.shared.data(from: url)
    guard let http = response as? HTTPURLResponse, http.statusCode == 200 else {
      throw ItemsError.invalidResponse
    }
    let items = try JSONDecoder().decode([Item].self, from: data)
    cache = items
    return items
  }
}

Commands

swift build
swift test
xcodebuild -scheme Inventory -destination 'platform=iOS Simulator,name=iPhone 16' test

Common pitfalls

Pitfall Why it hurts Fix
UI updates off main actor Crashes / warnings @MainActor
Retain cycles in closures Leaks [weak self]
Overusing classes Unexpected sharing Value types
Swallowing errors as optional Silent failures Propagate throws

Best practices

  • Use Result only when bridging non-throwing APIs; prefer throws in new code.
  • Prefer protocol existential erasure carefully - generics often clearer.
  • Keep access control (internal/public) intentional for modules.
  • Write XCTest/Swift Testing coverage for parsing and state transitions.

Limitations

  • ABI/module stability matters when shipping binary frameworks.
  • Swift Concurrency migration from GCD can be gradual and mixed.
  • Server-side Swift exists but differs from Apple platform tooling.

Related skills

  • @xcode-ios - Xcode signing, schemes, archives
  • @kotlin - peer language for Android
  • @firebase - common iOS backend SDKs