Skip to content
swift-fundamentals logo

Swift Fundamentals

swift-fundamentals

Swift 6.x language best practices, macros, project setup, and modern patterns. Use when user asks about Swift syntax, Package.swift configuration, project structure, macros like @Observable/@Model/@MainActor, property wrappers, or modern Swift development patterns.

NeverSight/skills_feed0installs215stars

SKILL.md

Full skill instructions

Swift Fundamentals

Comprehensive guide to Swift 6.x language features, best practices, macros, and project configuration for iOS 26 and macOS Tahoe development.

Prerequisites

  • Xcode 26+ or Swift 6.x toolchain
  • macOS 15.5+ (Sequoia) for full iOS 26 support

Swift Version Check

swift --version
# Swift version 6.x

Swift 6.x Key Features

Swift 6.0 - Major Changes

  1. Complete Concurrency Checking - Strict data-race safety by default
  2. Typed Throws - Functions can specify error types: throws(MyError)
  3. Noncopyable Types - ~Copyable for unique ownership
  4. Pack Iteration - Iterate over parameter packs
  5. 128-bit Integer Types - Int128 and UInt128
  6. count(where:) - Count elements matching predicate

Swift 6.2 - Recent Improvements

  1. Approachable Concurrency - Easier adoption path
  2. Single-threaded by default - New defaultIsolation setting
  3. Observations Async Sequence - Stream state changes
  4. Pre-built swift-syntax - Faster macro compilation
  5. InlineArray - Fixed-size inline storage

Swift 6.3 - Latest (2025)

  1. Enhanced Type Inference - Better generic inference
  2. Improved Error Messages - Clearer diagnostics
  3. Performance Optimizations - Faster compilation

Core Macros

@Observable (iOS 17+)

Modern replacement for ObservableObject. Automatically tracks property access.

import Observation

@Observable
class UserSettings {
    var username: String = ""
    var isLoggedIn: Bool = false
    var preferences: Preferences = Preferences()

    // Computed properties are also tracked
    var displayName: String {
        isLoggedIn ? username : "Guest"
    }
}

// Usage in SwiftUI
struct SettingsView: View {
    var settings: UserSettings  // No @ObservedObject needed

    var body: some View {
        Text(settings.displayName)
        // View automatically updates when displayName changes
    }
}

Key Differences from ObservableObject:

  • No @Published property wrappers needed
  • No objectWillChange publisher
  • Finer-grained updates (per-property, not whole object)
  • Use @Bindable for two-way bindings
struct EditView: View {
    @Bindable var settings: UserSettings

    var body: some View {
        TextField("Username", text: $settings.username)
    }
}

@Model (SwiftData)

Declares a SwiftData model with automatic persistence.

import SwiftData

@Model
class Note {
    var title: String
    var content: String
    var createdAt: Date
    var tags: [Tag]?  // Optional relationship for CloudKit

    init(title: String, content: String = "") {
        self.title = title
        self.content = content
        self.createdAt = Date()
    }
}

@Model
class Tag {
    var name: String
    var notes: [Note]?  // Inverse relationship

    init(name: String) {
        self.name = name
    }
}

Important for CloudKit Sync:

  • All relationships must be optional
  • No @Attribute(.unique) constraints
  • Default values required for non-optional properties

@MainActor

Ensures code runs on the main thread/​actor.

@MainActor
class ViewModel {
    var items: [Item] = []
    var isLoading = false

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

        // Network call can be off main actor
        let fetched = await fetchItems()

        // Assignment happens on main actor
        items = fetched
    }

    nonisolated func fetchItems() async -> [Item] {
        // This can run on any thread
        try? await URLSession.shared.data(from: url)
        // ...
    }
}

@Generable (Foundation Models - iOS 26)

Enables structured AI output generation.

import FoundationModels

@Generable
struct MovieRecommendation {
    var title: String
    var year: Int
    var genre: String
    var reason: String
}

// Usage
let session = LanguageModelSession()
let recommendation: MovieRecommendation = try await session.respond(
    to: "Recommend a sci-fi movie from the 2020s"
)

@Test (Swift Testing)

Marks a function as a test case.

import Testing

@Test("User can create account with valid email")
func createAccountWithValidEmail() async throws {
    let result = try await authService.createAccount(email: "[email protected]")
    #expect(result.success)
    #expect(result.user?.email == "[email protected]")
}

@Test("Password validation", arguments: [
    ("abc", false),
    ("abc12345", true),
    ("ABC12345!", true)
])
func validatePassword(password: String, expected: Bool) {
    #expect(validator.isValid(password) == expected)
}

Property Wrappers

SwiftUI Property Wrappers

struct ContentView: View {
    // Local state - view owns this value
    @State private var count = 0

    // Two-way binding from parent
    @Binding var selectedTab: Int

    // Environment value from system or parent
    @Environment(\.colorScheme) var colorScheme

    // Custom environment object
    @Environment(AppState.self) var appState

    // SwiftData query
    @Query(sort: \Note.createdAt, order: .reverse)
    var notes: [Note]

    // Focus state for text fields
    @FocusState private var isFocused: Bool

    // Namespace for matched geometry effects
    @Namespace private var animation

    var body: some View {
        // ...
    }
}

@Bindable (iOS 17+)

Creates bindings to @Observable properties.

struct EditorView: View {
    @Bindable var document: Document  // Document is @Observable

    var body: some View {
        TextEditor(text: $document.content)
        Toggle("Published", isOn: $document.isPublished)
    }
}

@AppStorage

Persists values to UserDefaults.

struct SettingsView: View {
    @AppStorage("hasCompletedOnboarding") var hasCompletedOnboarding = false
    @AppStorage("preferredTheme") var preferredTheme = "system"
    @AppStorage("notificationsEnabled") var notificationsEnabled = true

    var body: some View {
        Toggle("Notifications", isOn: $notificationsEnabled)
    }
}

@SceneStorage

Persists view state per scene (for state restoration).

struct DocumentView: View {
    @SceneStorage("selectedDocumentID") var selectedDocumentID: String?
    @SceneStorage("scrollPosition") var scrollPosition: Double = 0

    var body: some View {
        // State restored when scene is recreated
    }
}

Package.swift Configuration

Basic Package

// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
        .iOS(.v26),
        .macOS(.v26)
    ],
    products: [
        .library(name: "MyApp", targets: ["MyApp"])
    ],
    dependencies: [
        // External dependencies
    ],
    targets: [
        .target(
            name: "MyApp",
            dependencies: [],
            swiftSettings: [
                .enableExperimentalFeature("StrictConcurrency")
            ]
        ),
        .testTarget(
            name: "MyAppTests",
            dependencies: ["MyApp"]
        )
    ]
)

With Dependencies

// swift-tools-version: 6.0
import PackageDescription

let package = Package(
    name: "MyApp",
    platforms: [
        .iOS(.v26),
        .macOS(.v26)
    ],
    products: [
        .library(name: "MyApp", targets: ["MyApp"])
    ],
    dependencies: [
        .package(url: "https://github.com/​apple/​swift-algorithms", from: "1.2.0"),
        .package(url: "https://github.com/​apple/​swift-collections", from: "1.1.0"),
        .package(url: "https://github.com/​apple/​swift-async-algorithms", from: "1.0.0")
    ],
    targets: [
        .target(
            name: "MyApp",
            dependencies: [
                .product(name: "Algorithms", package: "swift-algorithms"),
                .product(name: "Collections", package: "swift-collections"),
                .product(name: "AsyncAlgorithms", package: "swift-async-algorithms")
            ]
        )
    ]
)

Strict Concurrency Settings

swiftSettings: [
    // Full Swift 6 concurrency
    .enableExperimentalFeature("StrictConcurrency"),

    // Or gradual adoption
    .swiftLanguageMode(.v6),

    // Enable upcoming features
    .enableUpcomingFeature("ExistentialAny"),
    .enableUpcomingFeature("InternalImportsByDefault")
]

Project Structure

Recommended Layout

MyApp/
├── Package.swift
├── Sources/
│   └── MyApp/
│       ├── App/
│       │   ├── MyAppApp.swift
│       │   └── AppState.swift
│       ├── Models/
│       │   ├── Note.swift
│       │   ├── Tag.swift
│       │   └── User.swift
│       ├── Views/
│       │   ├── ContentView.swift
│       │   ├── Notes/
│       │   │   ├── NoteListView.swift
│       │   │   ├── NoteDetailView.swift
│       │   │   └── NoteEditorView.swift
│       │   └── Settings/
│       │       └── SettingsView.swift
│       ├── Services/
│       │   ├── NetworkService.swift
│       │   └── StorageService.swift
│       ├── Utilities/
│       │   ├── Extensions/
│       │   └── Helpers/
│       └── Resources/
│           ├── Localizable.xcstrings
│           └── Assets.xcassets
└── Tests/
    └── MyAppTests/
        ├── ModelTests/
        ├── ServiceTests/
        └── ViewTests/

App Entry Point

import SwiftUI
import SwiftData

@main
struct MyAppApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: [Note.self, Tag.self])
    }
}

With Custom Container Configuration

@main
struct MyAppApp: App {
    let container: ModelContainer

    init() {
        let schema = Schema([Note.self, Tag.self])
        let config = ModelConfiguration(
            schema: schema,
            isStoredInMemoryOnly: false,
            cloudKitDatabase: .automatic  // Enable iCloud sync
        )

        do {
            container = try ModelContainer(for: schema, configurations: config)
        } catch {
            fatalError("Failed to configure SwiftData: \(error)")
        }
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(container)
    }
}

Modern Swift Patterns

Result Builders

@resultBuilder
struct HTMLBuilder {
    static func buildBlock(_ components: String...) -> String {
        components.joined()
    }

    static func buildOptional(_ component: String?) -> String {
        component ?? ""
    }

    static func buildEither(first component: String) -> String {
        component
    }

    static func buildEither(second component: String) -> String {
        component
    }
}

func html(@HTMLBuilder content: () -> String) -> String {
    "<html>\(content())</​html>"
}

let page = html {
    "<head><title>Hello</​title></​head>"
    "<body>"
    if showHeader {
        "<h1>Welcome</​h1>"
    }
    "<p>Content here</​p>"
    "</​body>"
}

Typed Throws (Swift 6)

enum NetworkError: Error {
    case invalidURL
    case noData
    case decodingFailed
}

func fetchUser(id: Int) throws(NetworkError) -> User {
    guard let url = URL(string: "https://api.example.com/​users/\(id)") else {
        throw .invalidURL
    }
    // ...
}

// Caller knows exactly what errors to handle
do {
    let user = try fetchUser(id: 123)
} catch .invalidURL {
    // Handle invalid URL
} catch .noData {
    // Handle no data
} catch .decodingFailed {
    // Handle decoding error
}

Noncopyable Types (Swift 6)

struct UniqueResource: ~Copyable {
    let handle: Int

    init(handle: Int) {
        self.handle = handle
    }

    deinit {
        // Clean up resource
        closeHandle(handle)
    }

    consuming func close() {
        // Explicitly consume the resource
    }
}

func useResource() {
    let resource = UniqueResource(handle: 42)
    // resource cannot be copied
    // processResource(resource)  // This moves resource
    // resource.doSomething()     // Error: resource was moved
}

Parameter Packs (Swift 6)

func all<each T: Equatable>(
    _ values: repeat each T,
    equalTo comparisons: repeat each T
) -> Bool {
    for (value, comparison) in repeat (each values, each comparisons) {
        if value != comparison {
            return false
        }
    }
    return true
}

let result = all(1, "hello", true, equalTo: 1, "hello", true)  // true

Error Handling Best Practices

Define Domain Errors

enum AppError: LocalizedError {
    case networkUnavailable
    case unauthorized
    case notFound(resource: String)
    case validationFailed(field: String, reason: String)
    case unknown(underlying: Error)

    var errorDescription: String? {
        switch self {
        case .networkUnavailable:
            return "Network connection unavailable"
        case .unauthorized:
            return "You are not authorized to perform this action"
        case .notFound(let resource):
            return "\(resource) was not found"
        case .validationFailed(let field, let reason):
            return "\(field): \(reason)"
        case .unknown(let error):
            return error.localizedDescription
        }
    }
}

Result Type Pattern

func fetchData() async -> Result<Data, AppError> {
    guard NetworkMonitor.shared.isConnected else {
        return .failure(.networkUnavailable)
    }

    do {
        let data = try await networkService.fetch()
        return .success(data)
    } catch {
        return .failure(.unknown(underlying: error))
    }
}

// Usage
switch await fetchData() {
case .success(let data):
    process(data)
case .failure(let error):
    showError(error)
}

Extensions Best Practices

Organize by Functionality

// String+Validation.swift
extension String {
    var isValidEmail: Bool {
        let pattern = #"^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$"#
        return range(of: pattern, options: .regularExpression) != nil
    }

    var isValidPassword: Bool {
        count >= 8 &&
        range(of: "[A-Z]", options: .regularExpression) != nil &&
        range(of: "[0-9]", options: .regularExpression) != nil
    }
}

// Date+Formatting.swift
extension Date {
    var relativeDescription: String {
        let formatter = RelativeDateTimeFormatter()
        formatter.unitsStyle = .short
        return formatter.localizedString(for: self, relativeTo: Date())
    }

    var iso8601String: String {
        ISO8601DateFormatter().string(from: self)
    }
}

// View+Modifiers.swift
extension View {
    func cardStyle() -> some View {
        modifier(CardModifier())
    }

    @ViewBuilder
    func `if`<Content: View>(_ condition: Bool, transform: (Self) -> Content) -> some View {
        if condition {
            transform(self)
        } else {
            self
        }
    }
}

Code Quality

SwiftLint Configuration

# .swiftlint.yml
included:
  - Sources
  - Tests

excluded:
  - .build
  - Package.swift

disabled_rules:
  - trailing_whitespace
  - line_length

opt_in_rules:
  - empty_count
  - explicit_init
  - closure_spacing
  - overridden_super_call
  - redundant_nil_coalescing
  - private_outlet
  - nimble_operator
  - attributes
  - operator_usage_whitespace
  - closure_end_indentation
  - first_where
  - object_literal
  - number_separator
  - prohibited_super_call
  - fatal_error_message
  - weak_delegate

line_length:
  warning: 120
  error: 200

type_body_length:
  warning: 300
  error: 500

file_length:
  warning: 500
  error: 1000

identifier_name:
  min_length: 2
  max_length: 50

Swift Format Configuration

// .swift-format
{
  "version": 1,
  "lineLength": 120,
  "indentation": {
    "spaces": 4
  },
  "tabWidth": 4,
  "maximumBlankLines": 1,
  "respectsExistingLineBreaks": true,
  "lineBreakBeforeControlFlowKeywords": false,
  "lineBreakBeforeEachArgument": false
}

Official Resources

More skills from NeverSight

devops-deployer logo
NeverSight/skills_feed

devops-deployer

Comprehensive DevOps and deployment workflow that orchestrates infrastructure automation, CI/CD pipelines, container orchestration, and cloud deployment. Handles everything from infrastructure as code and pipeline setup to monitoring, scaling, and disaster recovery.

215 1
View
avnu logo
NeverSight/skills_feed

avnu

Integrate avnu SDK for Starknet DeFi: token swaps with best-price routing, DCA recurring buys, native staking, gasless transactions via paymaster, and market data. Use when building Starknet trading, DEX aggregation, or DeFi automation features.

215 0
View
post-to-x logo
NeverSight/skills_feed

post-to-x

发布内容和文章到 X (Twitter)。支持带图片的普通推文和 X Articles(长文)。使用真实的 Chrome 和 CDP 来绕过自动化检测。

215 0
View
ralph-prompt-builder logo
NeverSight/skills_feed

ralph-prompt-builder

Master orchestrator for generating Ralph Wiggum-compatible prompts. Analyzes task requirements and routes to appropriate generator (single-task, multi-task, project, or research). Use when you need to create any Ralph loop prompt and want automatic selection of the right generator.

215 0
View
branch-comparison logo
NeverSight/skills_feed

branch-comparison

Use when the user asks to compare branches, analyze git diffs, review changes between branches, update specifications based on code changes, or analyze what changed. Triggers on keywords like "compare branches", "git diff", "what changed", "branch comparison", "code changes", "spec update".

215 0
View
fastapi-development logo
NeverSight/skills_feed

fastapi-development

Build high-performance FastAPI applications with async routes, validation, dependency injection, security, and automatic API documentation. Use when developing modern Python APIs with async support, automatic OpenAPI documentation, and high performance requirements.

215 0
View
zendesk-chat logo
NeverSight/skills_feed

zendesk-chat

Enables Claude to manage Zendesk Chat conversations, support tickets, and customer service operations

215 0
View
forge logo
NeverSight/skills_feed

forge

Mine transcripts for knowledge - decisions, learnings, failures, patterns. Triggers: "forge insights", "mine transcripts", "extract knowledge".

215 0
View
mixpanel logo
NeverSight/skills_feed

mixpanel

Track product analytics and user behavior with Mixpanel's event-based platform.

215 0
View
ocpp logo
NeverSight/skills_feed

ocpp

OCPP protocol reference for EV charging infrastructure development. Covers OCPP 2.0.1 and OCPP 1.6J. Use when working with OCPP messages, charging station code, CSMS/Central System backends, smart charging, transaction handling, or EV charging protocols. Activates on keywords: OCPP, charging stat...

215 0
View
bee-collect logo
NeverSight/skills_feed

bee-collect

Gather scattered ideas into organized GitHub issues. The bee collects pollen from every flower, checks if the hive already has it, and carefully deposits new work in the comb for later. Never edits code—only organizes the work ahead. Use when creating issues from TODOs or planning work.

215 0
View
vercel-react-native-skills logo
NeverSight/skills_feed

vercel-react-native-skills

Comprehensive best practices for React Native and Expo applications. Contains rules across multiple categories covering performance, animations, UI patterns, and platform-specific optimizations.

215 0
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View