Smithery Logo
MCPsSkillsDocsPricing
Login
Smithery Logo

Accelerating the Agent Economy

Resources

DocumentationPrivacy PolicySystem Status

Company

PricingAboutBlog

Connect

© 2026 Smithery. All rights reserved.

    dralgorhythm

    swift

    dralgorhythm/swift
    Coding
    4
    1 installs

    About

    SKILL.md

    Install

    Install via Skills CLI

    or add to your agent
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    ├─
    ├─
    └─

    About

    Write Swift code for iOS/macOS following best practices. Use when developing with SwiftUI, UIKit, or Swift packages. Covers type safety, concurrency, and tooling.

    SKILL.md

    Swift / iOS Development

    Project Setup

    Swift Package Manager

    # Initialize new package
    swift package init --type executable
    
    # Add dependencies to Package.swift
    # swift package update
    

    Package.swift

    // swift-tools-version: 5.10
    import PackageDescription
    
    let package = Package(
        name: "MyApp",
        platforms: [.iOS(.v17), .macOS(.v14)],
        products: [
            .library(name: "MyApp", targets: ["MyApp"]),
        ],
        dependencies: [
            // Add dependencies here
        ],
        targets: [
            .target(name: "MyApp", dependencies: []),
            .testTarget(name: "MyAppTests", dependencies: ["MyApp"]),
        ]
    )
    

    Xcode Project

    # Create new Xcode project via Xcode or:
    # Use SwiftUI App template for new projects
    # Target iOS 17+ for latest APIs
    

    Type Patterns

    Optionals

    // Safe unwrapping
    if let user = optionalUser {
        print(user.name)
    }
    
    // Guard for early exit
    guard let user = optionalUser else {
        return
    }
    
    // Optional chaining
    let name = user?.profile?.displayName ?? "Anonymous"
    
    // Nil coalescing
    let displayName = user?.name ?? "Guest"
    

    Result Type

    enum NetworkError: Error {
        case invalidURL
        case noData
        case decodingFailed
    }
    
    func fetchUser(id: String) async -> Result<User, NetworkError> {
        guard let url = URL(string: "https://api.example.com/users/\(id)") else {
            return .failure(.invalidURL)
        }
    
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            let user = try JSONDecoder().decode(User.self, from: data)
            return .success(user)
        } catch {
            return .failure(.decodingFailed)
        }
    }
    
    // Usage
    switch await fetchUser(id: "123") {
    case .success(let user):
        print("Got user: \(user.name)")
    case .failure(let error):
        print("Error: \(error)")
    }
    

    Protocols & Extensions

    protocol Identifiable {
        var id: UUID { get }
    }
    
    protocol Displayable {
        var displayName: String { get }
    }
    
    extension User: Identifiable, Displayable {
        var displayName: String {
            "\(firstName) \(lastName)"
        }
    }
    

    Error Handling

    // Throwing functions
    func loadConfig() throws -> Config {
        guard let data = FileManager.default.contents(atPath: configPath) else {
            throw ConfigError.fileNotFound
        }
        return try JSONDecoder().decode(Config.self, from: data)
    }
    
    // Do-catch
    do {
        let config = try loadConfig()
        print(config)
    } catch ConfigError.fileNotFound {
        print("Config file missing")
    } catch {
        print("Unknown error: \(error)")
    }
    
    // Try? for optional result
    let config = try? loadConfig()
    
    // Try! only when failure is impossible
    let bundledConfig = try! loadBundledConfig()
    

    Async/Await Patterns

    Basic Async

    func fetchUsers() async throws -> [User] {
        let (data, _) = try await URLSession.shared.data(from: usersURL)
        return try JSONDecoder().decode([User].self, from: data)
    }
    
    // Calling async functions
    Task {
        do {
            let users = try await fetchUsers()
            await MainActor.run {
                self.users = users
            }
        } catch {
            print("Failed: \(error)")
        }
    }
    

    Structured Concurrency

    // Parallel execution
    async let users = fetchUsers()
    async let posts = fetchPosts()
    let (userList, postList) = try await (users, posts)
    
    // Task groups
    func fetchAllUserData(ids: [String]) async throws -> [UserData] {
        try await withThrowingTaskGroup(of: UserData.self) { group in
            for id in ids {
                group.addTask {
                    try await fetchUserData(id: id)
                }
            }
            return try await group.reduce(into: []) { $0.append($1) }
        }
    }
    

    Actors

    actor UserCache {
        private var cache: [String: User] = [:]
    
        func get(_ id: String) -> User? {
            cache[id]
        }
    
        func set(_ user: User) {
            cache[user.id] = user
        }
    }
    
    // Usage
    let cache = UserCache()
    await cache.set(user)
    let cached = await cache.get("123")
    

    SwiftUI Patterns

    View with State

    struct ContentView: View {
        @State private var count = 0
        @State private var username = ""
    
        var body: some View {
            VStack(spacing: 16) {
                Text("Count: \(count)")
                    .font(.title)
    
                Button("Increment") {
                    count += 1
                }
    
                TextField("Username", text: $username)
                    .textFieldStyle(.roundedBorder)
            }
            .padding()
        }
    }
    

    Observable ViewModel

    @Observable
    class UserViewModel {
        var users: [User] = []
        var isLoading = false
        var error: Error?
    
        func loadUsers() async {
            isLoading = true
            defer { isLoading = false }
    
            do {
                users = try await userService.fetchAll()
            } catch {
                self.error = error
            }
        }
    }
    
    struct UserListView: View {
        @State private var viewModel = UserViewModel()
    
        var body: some View {
            List(viewModel.users) { user in
                UserRow(user: user)
            }
            .task {
                await viewModel.loadUsers()
            }
            .overlay {
                if viewModel.isLoading {
                    ProgressView()
                }
            }
        }
    }
    

    Environment & Dependency Injection

    // Define environment key
    struct UserServiceKey: EnvironmentKey {
        static let defaultValue: UserService = .live
    }
    
    extension EnvironmentValues {
        var userService: UserService {
            get { self[UserServiceKey.self] }
            set { self[UserServiceKey.self] = newValue }
        }
    }
    
    // Use in view
    struct ProfileView: View {
        @Environment(\.userService) private var userService
    
        var body: some View {
            // Use userService
        }
    }
    

    Testing

    Swift Testing (Swift 6+)

    import Testing
    
    @Suite("UserService Tests")
    struct UserServiceTests {
        let service = UserService()
    
        @Test("creates user with valid email")
        func createUser() async throws {
            let user = try await service.create(email: "test@example.com")
            #expect(user.email == "test@example.com")
        }
    
        @Test("throws on invalid email")
        func invalidEmail() async {
            await #expect(throws: ValidationError.self) {
                try await service.create(email: "invalid")
            }
        }
    
        @Test("fetches user by ID", arguments: ["user1", "user2", "user3"])
        func fetchUser(id: String) async throws {
            let user = try await service.fetch(id: id)
            #expect(user.id == id)
        }
    }
    

    XCTest (Legacy)

    import XCTest
    @testable import MyApp
    
    final class UserServiceTests: XCTestCase {
        var service: UserService!
    
        override func setUp() {
            super.setUp()
            service = UserService()
        }
    
        func testCreateUser() async throws {
            let user = try await service.create(email: "test@example.com")
            XCTAssertEqual(user.email, "test@example.com")
        }
    
        func testInvalidEmailThrows() async {
            do {
                _ = try await service.create(email: "invalid")
                XCTFail("Expected error")
            } catch {
                XCTAssertTrue(error is ValidationError)
            }
        }
    }
    

    Tooling

    # SwiftLint (linting)
    brew install swiftlint
    swiftlint lint
    swiftlint lint --fix
    
    # SwiftFormat (formatting)
    brew install swiftformat
    swiftformat .
    swiftformat . --lint
    
    # Run tests
    swift test
    xcodebuild test -scheme MyApp -destination 'platform=iOS Simulator,name=iPhone 15'
    
    # Build
    swift build
    xcodebuild build -scheme MyApp
    
    # fastlane (CI/CD)
    brew install fastlane
    fastlane init
    fastlane ios test
    fastlane ios beta  # Deploy to TestFlight
    

    .swiftlint.yml

    disabled_rules:
      - trailing_whitespace
      - line_length
    
    opt_in_rules:
      - empty_count
      - empty_string
    
    excluded:
      - Pods
      - .build
    

    .swiftformat

    --indent 4
    --allman false
    --wraparguments before-first
    --wrapparameters before-first
    --self remove
    --importgrouping alphabetized
    
    Recommended Servers
    Vercel Grep
    Vercel Grep
    Microsoft Learn MCP
    Microsoft Learn MCP
    OpenZeppelin
    OpenZeppelin
    Repository
    dralgorhythm/claude-agentic-framework
    Files