swift-conventions

Swift coding conventions and best practices for modern Swift development. Use when writing, reviewing, or refactoring Swift code to ensure consistency with naming conventions, access control, async/await patterns, and SwiftUI/framework best practices.

16 stars

Best use case

swift-conventions is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Swift coding conventions and best practices for modern Swift development. Use when writing, reviewing, or refactoring Swift code to ensure consistency with naming conventions, access control, async/await patterns, and SwiftUI/framework best practices.

Teams using swift-conventions should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/swift-conventions/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/development/swift-conventions/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/swift-conventions/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How swift-conventions Compares

Feature / Agentswift-conventionsStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Swift coding conventions and best practices for modern Swift development. Use when writing, reviewing, or refactoring Swift code to ensure consistency with naming conventions, access control, async/await patterns, and SwiftUI/framework best practices.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

Related Guides

SKILL.md Source

# Swift Coding Conventions

## Naming Conventions

### Types (Classes, Structs, Enums, Protocols)

Use **PascalCase** for all type names:

```swift
public class ProcessManager { }
public struct Location { }
public enum ProcessQuality { }
public protocol ProcessController { }
```

### Properties & Variables

Use **camelCase** for properties, variables, and instance names:

```swift
let locationManager = LocationManager()
var subscriptions: [ProcessSubscription] = []
private let updateInterval: TimeInterval = 60
```

### Functions & Methods

Use **camelCase** with descriptive action verbs:

```swift
func refreshData(for location: Location) async throws -> ProcessSensor?
func updateLocation(location: Location)
private func significantLocationChange(previous: Location?, current: Location) -> Bool
```

### Constants

Use **camelCase** for constant properties, **UPPER_SNAKE_CASE** for macro-like constants:

```swift
public static let houseOfWorldCultures = Location(latitude: 52.51889, longitude: 13.36528)
private let updateInterval: TimeInterval = 60
```

### Enums

Use **PascalCase** for enum name, **camelCase** for cases:

```swift
public enum ProcessQuality {
    case good
    case uncertain
    case bad
}

public enum ProcessSelector: Hashable {
    case weather(Weather)
    case forecast(Forecast)
}
```

## Code Structure

### Braces

Opening brace on same line, closing brace on new line:

```swift
public class ProcessManager {
    func updateSubscriptions() {
        for subscription in subscriptions {
            subscription.update(timeout: updateInterval)
        }
    }
}
```

### Indentation

- Use **4 spaces** (no tabs)
- Align continuation lines with opening delimiter

### Line Length

Target **120 characters** maximum per line. Break at logical points:

```swift
public func dataWithRetry(
    from url: URL, retryCount: Int = 3, retryInterval: TimeInterval = 1.0
) async throws -> (Data, URLResponse) {
    // Implementation
}
```

## Access Control

Always explicit: Mark APIs as `public` intentionally; avoid relying on default `internal`.

```swift
public class ProcessManager: Identifiable {
    public let id = UUID()
    public static let shared = ProcessManager()
    private let locationManager = LocationManager()
    private var location: Location?
}
```

Order of access levels (most to least restrictive):

1. `private` - Only within current declaration
2. `fileprivate` - Only within same source file
3. `internal` - Within module (default)
4. `public` - Visible to consumers
5. `open` - Visible and subclassable (use rarely)

## Type Declarations

### Classes

```swift
public class ProcessManager: Identifiable, LocationManagerDelegate {
    public let id = UUID()
    public static let shared = ProcessManager()
    private init() { }
}
```

### Structs

```swift
public struct Location: Equatable, Hashable {
    public let latitude: Double
    public let longitude: Double

    public init(latitude: Double, longitude: Double) {
        self.latitude = latitude
        self.longitude = longitude
    }
}
```

### Enums

```swift
public enum ProcessQuality {
    case good
    case uncertain
    case bad
    case unknown
}

public enum Weather: Int, CaseIterable {
    case temperature = 0
    case apparentTemperature = 1
}

public enum ProcessSelector: Hashable {
    case weather(Weather)
    case forecast(Forecast)
    case covid(Covid)
}
```

### Protocols

```swift
public protocol ProcessController {
    func refreshData(for location: Location) async throws -> ProcessSensor?
}

public protocol LocationManagerDelegate: Identifiable where ID == UUID {
    func locationManager(didUpdateLocation location: Location)
}
```

## Properties

### Stored Properties

```swift
public let id = UUID()
private let locationManager = LocationManager()
private var location: Location?
private let updateInterval: TimeInterval = 60
```

### Computed Properties

```swift
public var coordinate: CLLocationCoordinate2D {
    return CLLocationCoordinate2D(latitude: self.latitude, longitude: self.longitude)
}

var isReady: Bool {
    return location != nil && subscriptions.isEmpty == false
}
```

### Property Observers

```swift
var location: Location? {
    willSet {
        print("About to set location")
    }
    didSet {
        if location != oldValue {
            refreshSubscriptions()
        }
    }
}
```

### Lazy Properties

```swift
lazy var dateFormatter: DateFormatter = {
    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss.SSS"
    return formatter
}()
```

## Functions & Methods

### Basic Structure

```swift
public func refreshData(for location: Location) async throws -> ProcessSensor? {
    let weather = try await WeatherService.shared.weather(for: clLocation)
    return ProcessSensor(name: "", location: location, measurements: [:], timestamp: Date.now)
}
```

### Parameter Labels

Descriptive external labels; omit with underscore when appropriate:

```swift
func updateLocation(location: Location)
func add(subscriber: any ProcessSubscriber, timeout: TimeInterval)
func process(_ data: Data) -> Result
```

### Default Parameters

Place at end of parameter list:

```swift
public func dataWithRetry(
    from url: URL,
    retryCount: Int = 3,
    retryInterval: TimeInterval = 1.0
) async throws -> (Data, URLResponse) {
    // Implementation
}
```

### Multiple Initializers

Designated initializer with convenience initializers:

```swift
public init(value: Measurement<T>, customData: [String: Any]?, quality: ProcessQuality, timestamp: Date) {
    self.value = value
    self.customData = customData
    self.quality = quality
    self.timestamp = timestamp
}

public convenience init(value: Measurement<T>, quality: ProcessQuality) {
    self.init(value: value, customData: nil, quality: quality, timestamp: Date.now)
}
```

## Control Flow

### If Statements

```swift
if location != nil {
    refreshSubscriptions()
}

if let location = self.location {
    delegate.locationManager(didUpdateLocation: location)
}
```

### Guard Statements

```swift
guard let location = self.location else {
    return
}

guard let data = data,
      let response = response as? HTTPURLResponse,
      (200...299).contains(response.statusCode) else {
    throw NetworkError.invalidResponse
}
```

### For Loops

```swift
for subscription in subscriptions {
    subscription.update(timeout: updateInterval)
}

for (index, item) in items.enumerated() {
    print("\(index): \(item)")
}

for subscription in subscriptions where subscription.isPending() {
    subscription.reset()
}
```

### Switch Statements

```swift
switch quality {
    case .good:
        return "✓"
    case .uncertain:
        return "~"
    case .bad:
        return "✗"
    case .unknown:
        return "?"
}

switch connectionType {
    case .wifi, .ethernet:
        return true
    case .cellular:
        return false
}
```

## Error Handling

### Error Definitions

```swift
enum NetworkError: Error {
    case invalidResponse
    case serverError(statusCode: Int)
    case noData
}
```

### Throwing Functions

```swift
public func refreshData(for location: Location) async throws -> ProcessSensor? {
    let weather = try await WeatherService.shared.weather(for: clLocation)
    return sensor
}
```

### Try-Catch Blocks

```swift
do {
    let (data, response) = try await self.data(from: url)
    return (data, response)
} catch NetworkError.invalidResponse {
    return nil
} catch {
    print("Error: \(error)")
    return nil
}
```

### Optional Try

```swift
if let placemark = try? await geocoder.reverseGeocodeLocation(location).first {
    // Use placemark
}

let config = try! Configuration.load()  // Only if guaranteed to succeed
```

## Async/Await

### Async Functions

```swift
public func refreshData(for location: Location) async throws -> ProcessSensor? {
    let weather = try await WeatherService.shared.weather(for: clLocation)
    let placemark = await LocationManager.reverseGeocodeLocation(location: location)
    return ProcessSensor(/* ... */)
}
```

### Task Creation

```swift
Task {
    await delegate.refreshData(location: location)
}

Task {
    do {
        let result = try await fetchData()
        process(result)
    } catch {
        print("Error: \(error)")
    }
}
```

### Actor Usage

```swift
actor NetworkManager {
    private var isConnected = true

    func updateConnectionStatus(_ status: Bool) {
        self.isConnected = status
    }
}
```

### Sendable Conformance

```swift
public class UnitRadiation: Dimension, @unchecked Sendable {
    public static let sieverts = UnitRadiation(
        symbol: "Sv/h",
        converter: UnitConverterLinear(coefficient: 1.0)
    )
}
```

## Protocols & Extensions

### Protocol Conformance

```swift
public class ProcessManager: Identifiable, LocationManagerDelegate {
    // Implementation
}

extension ProcessManager: CustomStringConvertible {
    public var description: String {
        return "ProcessManager with \(subscriptions.count) subscriptions"
    }
}
```

### Extension Organization

Use MARK comments to organize extensions by purpose:

```swift
// MARK: - LocationManagerDelegate
extension ProcessManager: LocationManagerDelegate {
    public func locationManager(didUpdateLocation location: Location) {
        // Implementation
    }
}

// MARK: - Subscription Management
extension ProcessManager {
    public func add(subscriber: any ProcessSubscriber, timeout: TimeInterval) {
        // Implementation
    }
}
```

## Generics

### Generic Types

```swift
public struct ProcessValue<T: Dimension>: Identifiable {
    public let id = UUID()
    public let value: Measurement<T>
    public let quality: ProcessQuality
}
```

### Generic Functions

```swift
func measure<T: Dimension>(_ value: Double, unit: T) -> Measurement<T> {
    return Measurement(value: value, unit: unit)
}
```

### Type Erasure

```swift
private var subscribers: [UUID: any ProcessSubscriber] = [:]

public func add(subscriber: any ProcessSubscriber, timeout: TimeInterval) {
    subscribers[subscriber.id] = subscriber
}
```

## Comments & Documentation

### Single-Line Comments

Comment the "why", not the "what":

```swift
// Check if device is connected before attempting network request
guard ReachabilityManager.shared.isConnected else {
    throw URLError(.notConnectedToInternet)
}
```

### Documentation Comments

Use DocC-style documentation for public APIs:

```swift
/// A simple and fast logging facility with support for different log levels.
public class Trace {
    /// Creates a new Logger instance
    /// - Parameters:
    ///   - minimumLevel: Minimum level of logs to display
    ///   - showColors: Whether to use ANSI colors
    ///   - dateFormat: Format string for timestamps
    public init(
        minimumLevel: Level = .debug,
        showColors: Bool = true,
        dateFormat: String = "yyyy-MM-dd HH:mm:ss.SSS"
    ) {
        // Implementation
    }
}
```

### MARK Comments

```swift
public class WeatherController {
    // MARK: - Properties
    private let service = WeatherService.shared

    // MARK: - Initialization
    public init() { }

    // MARK: - Public Methods
    public func refreshData(for location: Location) async throws -> ProcessSensor? {
        // Implementation
    }

    // MARK: - Private Helpers
    private func processWeatherData(_ data: WeatherData) -> ProcessSensor {
        // Implementation
    }
}
```

## Formatting & Whitespace

### Blank Lines

Separate logical sections with blank lines:

```swift
public class ProcessManager {
    public let id = UUID()
    public static let shared = ProcessManager()

    private let locationManager = LocationManager()
    private var location: Location?

    public func refreshSubscriptions() {
        // Implementation
    }
}
```

### Spacing

- Space after comma: `[1, 2, 3]`
- Space around operators: `a + b`
- No space before colon, space after: `var dict: [String: Int] = [:]`
- No space around range operators: `for i in 0..<count`, `0...10`

### Trailing Whitespace

Remove all trailing whitespace at end of lines.

## Swift-Specific Patterns

### Optionals

```swift
if let location = self.location {
    process(location)
}

guard let location = self.location else {
    return
}

let count = subscribers[id]?.subscriptions.count
let value = optionalValue ?? defaultValue
```

### Type Inference

```swift
let manager = ProcessManager.shared
let id = UUID()
let values = [1, 2, 3]

let timeout: TimeInterval = 60  // Explicit when needed
```

### Closures

```swift
Timer.scheduledTimer(withTimeInterval: updateInterval, repeats: true) { _ in
    self.updateSubscriptions()
}

items.map { $0.value * 2 }

UIView.animate(withDuration: 0.3) {
    view.alpha = 0
} completion: { _ in
    view.removeFromSuperview()
}
```

### Collections

```swift
var subscriptions: [ProcessSubscription] = []
var measurements: [ProcessSelector: [ProcessValue<Dimension>]] = [:]
let uniqueIds: Set<UUID> = []
```

### Property Wrappers

```swift
@Published var measurements: [ProcessValue<Dimension>] = []
@AppStorage("refreshInterval") var refreshInterval: TimeInterval = 60
```

## Code Review Checklist

- [ ] All public APIs have explicit `public` access control
- [ ] All types follow naming conventions (PascalCase)
- [ ] All functions/properties follow naming conventions (camelCase)
- [ ] Code is formatted with 4-space indentation
- [ ] Documentation comments for public APIs
- [ ] Error handling is comprehensive
- [ ] Async/await used consistently
- [ ] No platform-specific UI dependencies in libraries
- [ ] Custom Dimension types conform to `@unchecked Sendable`
- [ ] Protocol conformance is explicit
- [ ] MARK comments organize code sections
- [ ] No force unwrapping (!) unless absolutely safe
- [ ] **CRITICAL: Always verify documentation against actual implementation**

## Architectural Patterns

### Controller Pattern

```swift
public class WeatherController: ProcessController {
    public func refreshData(for location: Location) async throws -> ProcessSensor? {
        // Fetch data from service
        // Process into ProcessSensor
        // Return structured data
    }
}
```

### Service Pattern

```swift
public class CovidService {
    static func fetchDistricts(for location: Location, radius: Double) async throws -> Data? {
        // Perform HTTP request
        // Return raw data
    }
}
```

### Transformer Pattern

```swift
public class WeatherTransformer: ProcessTransformer {
    override public func renderCurrent(measurements: [ProcessSelector: [ProcessValue<Dimension>]])
        -> [ProcessSelector: ProcessValue<Dimension>] {
        // Transform measurements into current values
    }
}
```

### Data Flow

Service (HTTP) → Controller (Parse) → Transformer (Process) → Consumer (Display)

Related Skills

swift-human-guidelines

16
from diegosouzapw/awesome-omni-skill

Comprehensive Swift 6 and SwiftUI development guidelines for building iOS 26, iOS 18, iPadOS, macOS, watchOS, visionOS, and tvOS applications. Covers Foundation Models API, BGContinuedProcessingTask, Call Translation API, Liquid Glass design system, data-race safety, typed throws, synchronization primitives, SwiftUI/UIKit interoperability, zoom transitions, and document-based apps. Use when building new Apple platform apps, implementing Apple Intelligence features, optimizing performance with Swift 6 concurrency, following Apple Human Interface Guidelines, creating cross-platform applications, or working with iOS 26/18 APIs. Triggers on Swift code, SwiftUI views, Xcode projects, app architecture, background processing, translation features, Foundation Models, synchronization, actors, Sendable types, or modern Apple platform development.

swift-concurrency

16
from diegosouzapw/awesome-omni-skill

Expert guidance on Swift Concurrency best practices, patterns, and implementation. Use when developers mention: (1) Swift Concurrency, async/await, actors, or tasks, (2) "use Swift Concurrency" or "modern concurrency patterns", (3) migrating to Swift 6, (4) data races or thread safety issues, (5) refactoring closures to async/await, (6) @MainActor, Sendable, or actor isolation, (7) concurrent code architecture or performance optimization, (8) concurrency-related linter warnings (SwiftLint or similar; e.g. async_without_await, Sendable/actor isolation/MainActor lint).

service-class-conventions

16
from diegosouzapw/awesome-omni-skill

Defines the structure and implementation of service classes, enforcing the use of interfaces, ServiceImpl classes, DTOs for data transfer, and transactional management.

moai-lang-swift

16
from diegosouzapw/awesome-omni-skill

Swift 6.0 enterprise development with async/await, SwiftUI, Combine, and Swift Concurrency. Advanced patterns for iOS, macOS, server-side Swift, and enterprise mobile applications with Context7 MCP integration.

memory-conventions

16
from diegosouzapw/awesome-omni-skill

This skill should be used when persisting context between sessions, saving project state, loading previous session context, or managing longitudinal memory beyond beads issue tracking.

function-ordering-conventions

16
from diegosouzapw/awesome-omni-skill

Defines the function ordering conventions, where functions that compose other functions appear earlier in the file, regardless of the file type.

banking-domain-conventions

16
from diegosouzapw/awesome-omni-skill

Use when writing code in a Firefly Banking Platform (firefly-oss) service — applies domain organization, service taxonomy, inter-service communication patterns, POM inheritance, and platform-specific conventions

axiom-swiftui-nav-diag

16
from diegosouzapw/awesome-omni-skill

Use when debugging navigation not responding, unexpected pops, deep links showing wrong screen, state lost on tab switch or background, crashes in navigationDestination, or any SwiftUI navigation failure - systematic diagnostics with production crisis defense

Action Pattern Conventions

16
from diegosouzapw/awesome-omni-skill

This skill should be used when the user asks about "Laravel action pattern", "action class naming", "how to structure actions", "React component patterns", "Node.js service structure", "framework-specific conventions", or discusses creating reusable, focused classes following action pattern conventions in Laravel, Symfony, React, Vue, or Node.js projects.

swiftui-expert-skill

16
from diegosouzapw/awesome-omni-skill

Write, review, or improve SwiftUI code following best practices for state management, view composition, performance, modern APIs, Swift concurrency, and iOS 26+ Liquid Glass adoption. Use when buil...

swiftui-components

16
from diegosouzapw/awesome-omni-skill

SwiftUI component expert for building reusable views, custom modifiers, view compositions, and Liquid Glass integration. Use when creating new SwiftUI views, refactoring UI code, applying design tokens, or building production-ready component libraries for macOS Tahoe (26) and iOS 26.

swift-api-design-guidelines-skill

16
from diegosouzapw/awesome-omni-skill

Write, review, or improve Swift APIs using Swift API Design Guidelines for naming, argument labels, documentation comments, terminology, and general conventions. Use when designing new APIs, refactoring existing interfaces, or reviewing API clarity and fluency.