
Swift
- 45 installs
- 19 repo stars
- Updated January 20, 2026
- miles990/claude-software-skills
Helps with ai & agent building tasks.
About
swift is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- swift
- AI & Agent Building
- AI-coding skill
Swift by the numbers
- 45 all-time installs (skills.sh)
- +1 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #7,727 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/miles990/claude-software-skills --skill swiftAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 45 |
|---|---|
| repo stars | ★ 19 |
| Last updated | January 20, 2026 |
| Repository | miles990/claude-software-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
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<NewSuccess>(_ transform: (Success) -> NewSuccess) -> Result<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..<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 <= 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
// swift-tools-version: 5.9
// ===========================================
// Swift Package Manager Template
// Usage: Copy to project root
// ===========================================
import PackageDescription
let package = Package(
name: "MyPackage",
platforms: [
.macOS(.v14),
.iOS(.v17),
.tvOS(.v17),
.watchOS(.v10),
.visionOS(.v1)
],
products: [
// Library product
.library(
name: "MyPackage",
targets: ["MyPackage"]
),
// Executable product
.executable(
name: "my-cli",
targets: ["MyCLI"]
),
],
dependencies: [
// HTTP client
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.19.0"),
// Argument parsing for CLI
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.3.0"),
// Logging
.package(url: "https://github.com/apple/swift-log.git", from: "1.5.0"),
// JSON handling
.package(url: "https://github.com/Flight-School/AnyCodable.git", from: "0.6.0"),
// Date handling
.package(url: "https://github.com/malcommac/SwiftDate.git", from: "7.0.0"),
// Testing (development only)
// .package(url: "https://github.com/Quick/Quick.git", from: "7.3.0"),
// .package(url: "https://github.com/Quick/Nimble.git", from: "13.2.0"),
],
targets: [
// Main library target
.target(
name: "MyPackage",
dependencies: [
.product(name: "AsyncHTTPClient", package: "async-http-client"),
.product(name: "Logging", package: "swift-log"),
.product(name: "AnyCodable", package: "AnyCodable"),
.product(name: "SwiftDate", package: "SwiftDate"),
],
path: "Sources/MyPackage",
swiftSettings: [
.enableUpcomingFeature("BareSlashRegexLiterals"),
.enableExperimentalFeature("StrictConcurrency"),
]
),
// CLI executable target
.executableTarget(
name: "MyCLI",
dependencies: [
"MyPackage",
.product(name: "ArgumentParser", package: "swift-argument-parser"),
],
path: "Sources/MyCLI"
),
// Test target
.testTarget(
name: "MyPackageTests",
dependencies: [
"MyPackage",
// .product(name: "Quick", package: "Quick"),
// .product(name: "Nimble", package: "Nimble"),
],
path: "Tests/MyPackageTests"
),
],
swiftLanguageVersions: [.v5]
)
Swift Templates
Swift Package Manager configuration templates.
Files
| Template | Purpose |
|---|---|
Package.swift | SPM package manifest |
Usage
Quick Start
# Create package
mkdir MyPackage && cd MyPackage
# Copy template
cp templates/Package.swift ./Package.swift
# Create directory structure
mkdir -p Sources/MyPackage Sources/MyCLI Tests/MyPackageTests
# Create initial files
touch Sources/MyPackage/MyPackage.swift
touch Sources/MyCLI/main.swift
touch Tests/MyPackageTests/MyPackageTests.swift
# Build
swift build
# Run CLI
swift run my-cli
# Test
swift testPackage Features
Products
| Product | Type | Description |
|---|---|---|
| MyPackage | Library | Main library |
| my-cli | Executable | CLI tool |
Dependencies
| Package | Purpose |
|---|---|
| async-http-client | HTTP networking |
| swift-argument-parser | CLI argument parsing |
| swift-log | Logging |
| AnyCodable | JSON handling |
| SwiftDate | Date utilities |
Platform Support
| Platform | Minimum Version |
|---|---|
| macOS | 14.0 |
| iOS | 17.0 |
| tvOS | 17.0 |
| watchOS | 10.0 |
| visionOS | 1.0 |
Project Structure
MyPackage/
├── Package.swift
├── Sources/
│ ├── MyPackage/
│ │ ├── MyPackage.swift
│ │ └── Models/
│ └── MyCLI/
│ └── main.swift
├── Tests/
│ └── MyPackageTests/
│ └── MyPackageTests.swift
└── README.mdCommon Commands
# Build
swift build
swift build -c release
# Run
swift run my-cli
# Test
swift test
swift test --filter MyPackageTests
# Clean
swift package clean
# Update dependencies
swift package update
# Generate Xcode project
swift package generate-xcodeprojCLI Example
// Sources/MyCLI/main.swift
import ArgumentParser
import MyPackage
@main
struct MyCLI: ParsableCommand {
static let configuration = CommandConfiguration(
commandName: "my-cli",
abstract: "A Swift CLI tool"
)
@Argument(help: "Input value")
var input: String
@Flag(name: .shortAndLong, help: "Verbose output")
var verbose = false
func run() throws {
print("Processing: \(input)")
}
}Library Example
// Sources/MyPackage/MyPackage.swift
import Logging
public struct MyPackage {
private let logger = Logger(label: "com.example.mypackage")
public init() {}
public func process(_ input: String) async throws -> String {
logger.info("Processing input")
return input.uppercased()
}
}Customization
Add iOS-only target
.target(
name: "MyiOSFeature",
dependencies: ["MyPackage"],
path: "Sources/MyiOSFeature"
),Add plugin
.plugin(
name: "MyPlugin",
capability: .buildTool()
)Enable Swift 6 features
swiftSettings: [
.enableUpcomingFeature("ExistentialAny"),
.enableUpcomingFeature("StrictConcurrency"),
]Related skills
AI & Agent Buildingagents