swift

Swift programming patterns including protocols, generics, async/await, and SwiftUI.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "swift" with this command: npx skills add miles990/claude-software-skills/miles990-claude-software-skills-swift

Swift

Overview

Swift programming patterns including protocols, generics, async/await, and SwiftUI.

Swift Fundamentals

Structs and Classes

import Foundation

// Struct (value type, preferred for most cases) struct User: Identifiable, Codable { let id: UUID var email: String var name: String var createdAt: Date

// Memberwise initializer provided automatically
// Custom initializer
init(email: String, name: String) {
    self.id = UUID()
    self.email = email
    self.name = name
    self.createdAt = Date()
}

// Computed property
var displayName: String {
    "\(name) <\(email)>"
}

// Mutating method (for structs)
mutating func updateEmail(_ newEmail: String) {
    email = newEmail
}

}

// Class (reference type) class UserManager { static let shared = UserManager() // Singleton

private var users: [UUID: User] = [:]

private init() {}

func add(_ user: User) {
    users[user.id] = user
}

func find(id: UUID) -> User? {
    users[id]
}

}

// Actor (thread-safe reference type) actor UserStore { private var users: [UUID: User] = [:]

func add(_ user: User) {
    users[user.id] = user
}

func find(id: UUID) -> User? {
    users[id]
}

func count() -> Int {
    users.count
}

}

Enums and Pattern Matching

// Enum with associated values enum Result<Success, Failure: Error> { case success(Success) case failure(Failure)

var isSuccess: Bool {
    if case .success = self { return true }
    return false
}

func map&#x3C;NewSuccess>(_ transform: (Success) -> NewSuccess) -> Result&#x3C;NewSuccess, Failure> {
    switch self {
    case .success(let value):
        return .success(transform(value))
    case .failure(let error):
        return .failure(error)
    }
}

}

// Enum with raw values enum Status: String, Codable, CaseIterable { case pending = "pending" case active = "active" case inactive = "inactive"

var displayName: String {
    switch self {
    case .pending: return "Pending Review"
    case .active: return "Active"
    case .inactive: return "Inactive"
    }
}

}

// Pattern matching func process(_ result: Result<User, Error>) { switch result { case .success(let user) where user.email.contains("@admin"): print("Admin user: (user.name)") case .success(let user): print("Regular user: (user.name)") case .failure(let error): print("Error: (error.localizedDescription)") } }

// If-case pattern if case .success(let user) = result { print(user.name) }

// Guard-case pattern func handleSuccess(_ result: Result<User, Error>) -> User? { guard case .success(let user) = result else { return nil } return user }

Optionals

// Optional declaration var name: String? = nil var age: Int? = 25

// Optional binding if let name = name { print("Name: (name)") }

// Multiple bindings if let name = name, let age = age, age > 18 { print("(name) is (age) years old") }

// Guard let (early exit) func processUser(_ user: User?) -> String { guard let user = user else { return "No user" } return user.displayName }

// Nil coalescing let displayName = name ?? "Anonymous"

// Optional chaining let uppercased = name?.uppercased()

// Map and flatMap let nameLength = name.map { $0.count } let parsed: Int? = "42".flatMap { Int($0) }

// Implicitly unwrapped (use sparingly) var apiKey: String!

Protocols and Generics

Protocols

// Protocol definition protocol Repository { associatedtype Entity: Identifiable

func find(id: Entity.ID) async throws -> Entity?
func findAll() async throws -> [Entity]
func save(_ entity: Entity) async throws
func delete(id: Entity.ID) async throws

}

// Protocol with default implementation extension Repository { func findAll() async throws -> [Entity] { // Default implementation [] } }

// Protocol composition protocol Named { var name: String { get } }

protocol Aged { var age: Int { get } }

typealias Person = Named & Aged

func greet(_ person: some Person) { print("Hello, (person.name)!") }

// Protocol with Self requirement protocol Copyable { func copy() -> Self }

// Conforming to protocols struct UserRepository: Repository { typealias Entity = User

func find(id: UUID) async throws -> User? {
    // Implementation
    nil
}

func save(_ entity: User) async throws {
    // Implementation
}

func delete(id: UUID) async throws {
    // Implementation
}

}

Generics

// Generic function func swap<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp }

// Generic type struct Stack<Element> { private var items: [Element] = []

mutating func push(_ item: Element) {
    items.append(item)
}

mutating func pop() -> Element? {
    items.popLast()
}

var top: Element? {
    items.last
}

var isEmpty: Bool {
    items.isEmpty
}

}

// Generic constraints func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? { for (index, item) in array.enumerated() { if item == value { return index } } return nil }

// Where clause func allItemsMatch<C1: Container, C2: Container>( _ c1: C1, _ c2: C2 ) -> Bool where C1.Item == C2.Item, C1.Item: Equatable { guard c1.count == c2.count else { return false }

for i in 0..&#x3C;c1.count {
    if c1[i] != c2[i] { return false }
}
return true

}

// Opaque types (some) func makeCollection() -> some Collection { [1, 2, 3] }

// Primary associated types (Swift 5.7+) func process<C: Collection<String>>(_ collection: C) { for item in collection { print(item) } }

Async/Await (Swift 5.5+)

// Async function func fetchUser(id: String) async throws -> User { let url = URL(string: "https://api.example.com/users/\(id)")! let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(User.self, from: data) }

// Concurrent execution func fetchAllUsers(ids: [String]) async throws -> [User] { try await withThrowingTaskGroup(of: User.self) { group in for id in ids { group.addTask { try await fetchUser(id: id) } }

    var users: [User] = []
    for try await user in group {
        users.append(user)
    }
    return users
}

}

// Async sequences struct NumberSequence: AsyncSequence { typealias Element = Int

let start: Int
let end: Int

struct AsyncIterator: AsyncIteratorProtocol {
    var current: Int
    let end: Int

    mutating func next() async -> Int? {
        guard current &#x3C;= end else { return nil }
        defer { current += 1 }
        try? await Task.sleep(nanoseconds: 100_000_000)
        return current
    }
}

func makeAsyncIterator() -> AsyncIterator {
    AsyncIterator(current: start, end: end)
}

}

// Using async for-in func processNumbers() async { for await number in NumberSequence(start: 1, end: 10) { print(number) } }

// Task groups func processItems(_ items: [Item]) async throws -> [Result] { try await withThrowingTaskGroup(of: Result.self) { group in for item in items { group.addTask { try await process(item) } } return try await group.reduce(into: []) { $0.append($1) } } }

// Actors for thread-safe state actor Counter { private var value = 0

func increment() {
    value += 1
}

func get() -> Int {
    value
}

}

// @MainActor for UI updates @MainActor class ViewModel: ObservableObject { @Published var users: [User] = []

func loadUsers() async {
    do {
        let fetched = try await fetchAllUsers(ids: ["1", "2", "3"])
        users = fetched
    } catch {
        print(error)
    }
}

}

SwiftUI Patterns

import SwiftUI

// View composition struct UserListView: View { @StateObject private var viewModel = UserListViewModel()

var body: some View {
    NavigationStack {
        List(viewModel.users) { user in
            NavigationLink(value: user) {
                UserRow(user: user)
            }
        }
        .navigationTitle("Users")
        .navigationDestination(for: User.self) { user in
            UserDetailView(user: user)
        }
        .refreshable {
            await viewModel.refresh()
        }
        .task {
            await viewModel.loadUsers()
        }
    }
}

}

struct UserRow: View { let user: User

var body: some View {
    HStack {
        AsyncImage(url: user.avatarURL) { image in
            image
                .resizable()
                .aspectRatio(contentMode: .fill)
        } placeholder: {
            ProgressView()
        }
        .frame(width: 44, height: 44)
        .clipShape(Circle())

        VStack(alignment: .leading) {
            Text(user.name)
                .font(.headline)
            Text(user.email)
                .font(.subheadline)
                .foregroundColor(.secondary)
        }
    }
}

}

// View model with Combine @MainActor class UserListViewModel: ObservableObject { @Published var users: [User] = [] @Published var isLoading = false @Published var error: Error?

private let userService: UserService

init(userService: UserService = .shared) {
    self.userService = userService
}

func loadUsers() async {
    isLoading = true
    defer { isLoading = false }

    do {
        users = try await userService.fetchUsers()
    } catch {
        self.error = error
    }
}

func refresh() async {
    await loadUsers()
}

}

// Custom view modifier struct CardModifier: ViewModifier { func body(content: Content) -> some View { content .padding() .background(Color(.systemBackground)) .cornerRadius(12) .shadow(radius: 4) } }

extension View { func card() -> some View { modifier(CardModifier()) } }

// Environment values private struct UserServiceKey: EnvironmentKey { static let defaultValue = UserService.shared }

extension EnvironmentValues { var userService: UserService { get { self[UserServiceKey.self] } set { self[UserServiceKey.self] = newValue } } }

Error Handling

// Define errors enum NetworkError: Error, LocalizedError { case invalidURL case noData case decodingFailed(Error) case serverError(statusCode: Int)

var errorDescription: String? {
    switch self {
    case .invalidURL:
        return "Invalid URL"
    case .noData:
        return "No data received"
    case .decodingFailed(let error):
        return "Decoding failed: \(error.localizedDescription)"
    case .serverError(let code):
        return "Server error: \(code)"
    }
}

}

// Throwing functions func fetchData(from urlString: String) async throws -> Data { guard let url = URL(string: urlString) else { throw NetworkError.invalidURL }

let (data, response) = try await URLSession.shared.data(from: url)

guard let httpResponse = response as? HTTPURLResponse else {
    throw NetworkError.noData
}

guard (200...299).contains(httpResponse.statusCode) else {
    throw NetworkError.serverError(statusCode: httpResponse.statusCode)
}

return data

}

// Result type func fetchUser(id: String) async -> Result<User, NetworkError> { do { let data = try await fetchData(from: "https://api.example.com/users/\(id)") let user = try JSONDecoder().decode(User.self, from: data) return .success(user) } catch let error as NetworkError { return .failure(error) } catch { return .failure(.decodingFailed(error)) } }

// Do-catch do { let user = try await fetchData(from: "...") print(user) } catch NetworkError.invalidURL { print("Bad URL") } catch { print("Other error: (error)") }

// try? and try! let user = try? await fetchUser(id: "1") // Returns optional let definiteUser = try! loadFromCache() // Force unwrap (crashes on error)

Related Skills

  • [[mobile]] - iOS/macOS development

  • [[frontend]] - SwiftUI patterns

  • [[testing]] - XCTest, Quick/Nimble

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

code-quality

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

game-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

devops-cicd

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

flame-game-dev

No summary provided by upstream source.

Repository SourceNeeds Review