swift-macos

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

macOS App Development - Swift 6.2

macOS应用开发 - Swift 6.2

Build native macOS apps with Swift 6.2 (latest: 6.2.4, Feb 2026), SwiftUI, SwiftData, and macOS 26 Tahoe. Target macOS 14+ for SwiftData/@Observable, macOS 15+ for latest SwiftUI, macOS 26 for Liquid Glass and Foundation Models.
使用Swift 6.2(最新版本:6.2.4,2026年2月)、SwiftUI、SwiftData和macOS 26 Tahoe构建原生macOS应用。SwiftData/@Observable需要最低目标macOS 14+,最新SwiftUI特性需要macOS 15+,Liquid Glass和Foundation Models需要macOS 26+。

Quick Start

快速开始

swift
import SwiftUI
import SwiftData

@Model
final class Project {
    var name: String
    var createdAt: Date
    @Relationship(deleteRule: .cascade) var tasks: [Task] = []

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

@Model
final class Task {
    var title: String
    var isComplete: Bool
    var project: Project?

    init(title: String) {
        self.title = title
        self.isComplete = false
    }
}

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup("Projects") {
            ContentView()
        }
        .modelContainer(for: [Project.self, Task.self])
        .defaultSize(width: 900, height: 600)

        #if os(macOS)
        Settings { SettingsView() }

        MenuBarExtra("Status", systemImage: "circle.fill") {
            MenuBarView()
        }
        .menuBarExtraStyle(.window)
        #endif
    }
}

struct ContentView: View {
    @Query(sort: \Project.createdAt, order: .reverse)
    private var projects: [Project]

    @Environment(\.modelContext) private var context
    @State private var selected: Project?

    var body: some View {
        NavigationSplitView {
            List(projects, selection: $selected) { project in
                NavigationLink(value: project) {
                    Text(project.name)
                }
            }
            .navigationSplitViewColumnWidth(min: 200, ideal: 250)
        } detail: {
            if let selected {
                DetailView(project: selected)
            } else {
                ContentUnavailableView("Select a Project",
                    systemImage: "sidebar.left")
            }
        }
    }
}
swift
import SwiftUI
import SwiftData

@Model
final class Project {
    var name: String
    var createdAt: Date
    @Relationship(deleteRule: .cascade) var tasks: [Task] = []

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

@Model
final class Task {
    var title: String
    var isComplete: Bool
    var project: Project?

    init(title: String) {
        self.title = title
        self.isComplete = false
    }
}

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup("Projects") {
            ContentView()
        }
        .modelContainer(for: [Project.self, Task.self])
        .defaultSize(width: 900, height: 600)

        #if os(macOS)
        Settings { SettingsView() }

        MenuBarExtra("Status", systemImage: "circle.fill") {
            MenuBarView()
        }
        .menuBarExtraStyle(.window)
        #endif
    }
}

struct ContentView: View {
    @Query(sort: \Project.createdAt, order: .reverse)
    private var projects: [Project]

    @Environment(\.modelContext) private var context
    @State private var selected: Project?

    var body: some View {
        NavigationSplitView {
            List(projects, selection: $selected) { project in
                NavigationLink(value: project) {
                    Text(project.name)
                }
            }
            .navigationSplitViewColumnWidth(min: 200, ideal: 250)
        } detail: {
            if let selected {
                DetailView(project: selected)
            } else {
                ContentUnavailableView("选择一个项目",
                    systemImage: "sidebar.left")
            }
        }
    }
}

Scenes & Windows

场景与窗口

ScenePurpose
WindowGroup
Resizable windows (multiple instances)
Window
Single-instance utility window
Settings
Preferences (Cmd+,)
MenuBarExtra
Menu bar with
.menu
or
.window
style
DocumentGroup
Document-based apps
Open windows:
@Environment(\.openWindow) var openWindow; openWindow(id: "about")
For complete scene lifecycle, see
references/app-lifecycle.md
.
场景用途
WindowGroup
可调整大小的窗口(支持多实例)
Window
单实例工具窗口
Settings
偏好设置(快捷键Cmd+,)
MenuBarExtra
菜单栏,支持
.menu
.window
样式
DocumentGroup
基于文档的应用
打开窗口:
@Environment(\.openWindow) var openWindow; openWindow(id: "about")
如需了解完整的场景生命周期,请查看
references/app-lifecycle.md

Menus & Commands

菜单与命令

swift
.commands {
    CommandGroup(replacing: .newItem) {
        Button("New Project") { /* ... */ }
            .keyboardShortcut("n", modifiers: .command)
    }
    CommandMenu("Tools") {
        Button("Run Analysis") { /* ... */ }
            .keyboardShortcut("r", modifiers: [.command, .shift])
    }
}
swift
.commands {
    CommandGroup(replacing: .newItem) {
        Button("新建项目") { /* ... */ }
            .keyboardShortcut("n", modifiers: .command)
    }
    CommandMenu("工具") {
        Button("运行分析") { /* ... */ }
            .keyboardShortcut("r", modifiers: [.command, .shift])
    }
}

Table (macOS-native)

表格(macOS原生)

swift
Table(items, selection: $selectedIDs, sortOrder: $sortOrder) {
    TableColumn("Name", value: \.name)
    TableColumn("Date") { Text($0.date, format: .dateTime) }
        .width(min: 100, ideal: 150)
}
.contextMenu(forSelectionType: Item.ID.self) { ids in
    Button("Delete", role: .destructive) { delete(ids) }
}
For forms, popovers, sheets, inspector, and macOS modifiers, see
references/swiftui-macos.md
.
swift
Table(items, selection: $selectedIDs, sortOrder: $sortOrder) {
    TableColumn("名称", value: \.name)
    TableColumn("日期") { Text($0.date, format: .dateTime) }
        .width(min: 100, ideal: 150)
}
.contextMenu(forSelectionType: Item.ID.self) { ids in
    Button("删除", role: .destructive) { delete(ids) }
}
如需了解表单、弹出框、面板、检查器及macOS修饰器,请查看
references/swiftui-macos.md

@Observable

@Observable

swift
@Observable
final class AppState {
    var projects: [Project] = []
    var isLoading = false

    func load() async throws {
        isLoading = true
        defer { isLoading = false }
        projects = try await ProjectService.fetchAll()
    }
}

// Use: @State var state = AppState()          (owner)
// Pass: .environment(state)                    (inject)
// Read: @Environment(AppState.self) var state  (child)
swift
@Observable
final class AppState {
    var projects: [Project] = []
    var isLoading = false

    func load() async throws {
        isLoading = true
        defer { isLoading = false }
        projects = try await ProjectService.fetchAll()
    }
}

// 使用方式: @State var state = AppState()          (所有者)
// 注入: .environment(state)                    (注入环境)
// 读取: @Environment(AppState.self) var state  (子视图)

SwiftData

SwiftData

@Query & #Predicate

@Query & #Predicate

swift
@Query(filter: #Predicate<Project> { !$0.isArchived }, sort: \Project.name)
private var active: [Project]

// Dynamic predicate
func search(_ term: String) -> Predicate<Project> {
    #Predicate { $0.name.localizedStandardContains(term) }
}

// FetchDescriptor (outside views)
var desc = FetchDescriptor<Project>(predicate: #Predicate { $0.isArchived })
desc.fetchLimit = 50
let results = try context.fetch(desc)
let count = try context.fetchCount(desc)
swift
@Query(filter: #Predicate<Project> { !$0.isArchived }, sort: \Project.name)
private var active: [Project]

// 动态谓词
func search(_ term: String) -> Predicate<Project> {
    #Predicate { $0.name.localizedStandardContains(term) }
}

// FetchDescriptor(视图外使用)
var desc = FetchDescriptor<Project>(predicate: #Predicate { $0.isArchived })
desc.fetchLimit = 50
let results = try context.fetch(desc)
let count = try context.fetchCount(desc)

Relationships

关联关系

swift
@Model final class Author {
    var name: String
    @Relationship(deleteRule: .cascade, inverse: \Book.author)
    var books: [Book] = []
}

@Model final class Book {
    var title: String
    var author: Author?
    @Relationship var tags: [Tag] = []  // many-to-many
}
Delete rules:
.cascade
,
.nullify
(default),
.deny
,
.noAction
.
swift
@Model final class Author {
    var name: String
    @Relationship(deleteRule: .cascade, inverse: \Book.author)
    var books: [Book] = []
}

@Model final class Book {
    var title: String
    var author: Author?
    @Relationship var tags: [Tag] = []  // 多对多
}
删除规则:
.cascade
.nullify
(默认)、
.deny
.noAction

Schema Migration

架构迁移

swift
enum SchemaV1: VersionedSchema { /* ... */ }
enum SchemaV2: VersionedSchema { /* ... */ }

enum MigrationPlan: SchemaMigrationPlan {
    static var schemas: [any VersionedSchema.Type] { [SchemaV1.self, SchemaV2.self] }
    static var stages: [MigrationStage] {
        [.lightweight(fromVersion: SchemaV1.self, toVersion: SchemaV2.self)]
    }
}

// Apply: .modelContainer(for: Model.self, migrationPlan: MigrationPlan.self)
swift
enum SchemaV1: VersionedSchema { /* ... */ }
enum SchemaV2: VersionedSchema { /* ... */ }

enum MigrationPlan: SchemaMigrationPlan {
    static var schemas: [any VersionedSchema.Type] { [SchemaV1.self, SchemaV2.self] }
    static var stages: [MigrationStage] {
        [.lightweight(fromVersion: SchemaV1.self, toVersion: SchemaV2.self)]
    }
}

// 应用迁移: .modelContainer(for: Model.self, migrationPlan: MigrationPlan.self)

CloudKit Sync

CloudKit同步

Enable iCloud capability, then
.modelContainer(for: Model.self)
auto-syncs. Constraints: all properties need defaults/optional, no unique constraints, optional relationships.
For model attributes, background contexts, batch ops, undo/redo, and testing, see SwiftData references below.
启用iCloud功能后,
.modelContainer(for: Model.self)
会自动同步。约束条件:所有属性需要默认值或设为可选,无唯一约束,关联关系需为可选。
如需了解模型属性、后台上下文、批量操作、撤销/重做及测试,请查看下方的SwiftData参考文档。

Concurrency (Swift 6.2)

并发编程(Swift 6.2)

Default MainActor Isolation

默认MainActor隔离

Opt entire module into main actor - all code runs on main actor by default:
swift
// Package.swift
.executableTarget(name: "MyApp", swiftSettings: [
    .defaultIsolation(MainActor.self),
])
Or Xcode: Build Settings > Swift Compiler > Default Isolation > MainActor.
将整个模块设置为默认MainActor隔离 - 所有代码默认在MainActor上运行:
swift
// Package.swift
.executableTarget(name: "MyApp", swiftSettings: [
    .defaultIsolation(MainActor.self),
])
或在Xcode中设置:Build Settings > Swift Compiler > Default Isolation > MainActor。

@concurrent

@concurrent

Mark functions for background execution:
swift
@concurrent
func processFile(_ url: URL) async throws -> Data {
    let data = try Data(contentsOf: url)
    return try compress(data) // runs off main actor
}
// After await, automatically back on main actor
let result = try await processFile(fileURL)
Use for CPU-intensive work, I/O, anything not touching UI.
标记函数用于后台执行:
swift
@concurrent
func processFile(_ url: URL) async throws -> Data {
    let data = try Data(contentsOf: url)
    return try compress(data) // 在非MainActor上运行
}
// await后,自动回到MainActor
let result = try await processFile(fileURL)
适用于CPU密集型任务、I/O操作及任何不涉及UI的工作。

Actors

参与者(Actors)

swift
actor DocumentStore {
    private var docs: [UUID: Document] = [:]
    func add(_ doc: Document) { docs[doc.id] = doc }
    func get(_ id: UUID) -> Document? { docs[id] }
    nonisolated let name: String
}
// Requires await: let doc = await store.get(id)
swift
actor DocumentStore {
    private var docs: [UUID: Document] = [:]
    func add(_ doc: Document) { docs[doc.id] = doc }
    func get(_ id: UUID) -> Document? { docs[id] }
    nonisolated let name: String
}
// 需要使用await: let doc = await store.get(id)

Structured Concurrency

结构化并发

swift
// Parallel with async let
func loadDashboard() async throws -> Dashboard {
    async let profile = fetchProfile()
    async let stats = fetchStats()
    return try await Dashboard(profile: profile, stats: stats)
}

// Dynamic with TaskGroup
func processImages(_ urls: [URL]) async throws -> [NSImage] {
    try await withThrowingTaskGroup(of: (Int, NSImage).self) { group in
        for (i, url) in urls.enumerated() {
            group.addTask { (i, try await loadImage(url)) }
        }
        var results = [(Int, NSImage)]()
        for try await r in group { results.append(r) }
        return results.sorted { $0.0 < $1.0 }.map(\.1)
    }
}
swift
// 使用async let实现并行
func loadDashboard() async throws -> Dashboard {
    async let profile = fetchProfile()
    async let stats = fetchStats()
    return try await Dashboard(profile: profile, stats: stats)
}

// 使用TaskGroup实现动态并发
func processImages(_ urls: [URL]) async throws -> [NSImage] {
    try await withThrowingTaskGroup(of: (Int, NSImage).self) { group in
        for (i, url) in urls.enumerated() {
            group.addTask { (i, try await loadImage(url)) }
        }
        var results = [(Int, NSImage)]()
        for try await r in group { results.append(r) }
        return results.sorted { $0.0 < $1.0 }.map(\.1)
    }
}

Sendable

Sendable

swift
struct Point: Sendable { var x, y: Double }              // value types: implicit
final class Config: Sendable { let apiURL: URL }          // final + immutable
actor SharedState { var count = 0 }                       // mutable: use actors
// Enable strict mode: .swiftLanguageMode(.v6) in Package.swift
swift
struct Point: Sendable { var x, y: Double }              // 值类型:隐式符合
final class Config: Sendable { let apiURL: URL }          // final类+不可变属性
actor SharedState { var count = 0 }                       // 可变状态:使用Actor
// 启用严格模式: .swiftLanguageMode(.v6) in Package.swift

AsyncSequence & Observations

AsyncSequence & 观察

swift
// Stream @Observable changes (Swift 6.2)
for await state in Observations(of: manager) {
    print(state.progress)
}

// Typed NotificationCenter (Swift 6.2)
struct DocSaved: MainActorMessage { let id: UUID }
NotificationCenter.default.post(DocSaved(id: doc.id))
for await n in NotificationCenter.default.notifications(of: DocSaved.self) {
    refresh(n.id)
}
For concurrency deep dives, see concurrency references below.
swift
// 监听@Observable对象的变化(Swift 6.2)
for await state in Observations(of: manager) {
    print(state.progress)
}

// 类型化NotificationCenter(Swift 6.2)
struct DocSaved: MainActorMessage { let id: UUID }
NotificationCenter.default.post(DocSaved(id: doc.id))
for await n in NotificationCenter.default.notifications(of: DocSaved.self) {
    refresh(n.id)
}
如需深入了解并发编程,请查看下方的并发参考文档。

Foundation Models (macOS 26+)

Foundation Models(macOS 26+)

On-device ~3B LLM. Free, offline, private:
swift
import FoundationModels

let session = LanguageModelSession()
let response = try await session.respond(to: "Summarize: \(text)")

// Structured output
@Generable struct Summary { var title: String; var points: [String] }
let result: Summary = try await session.respond(to: prompt, generating: Summary.self)
For tool calling, streaming, and sessions, see
references/foundation-models.md
.
本地部署的约30亿参数大语言模型。免费、离线、隐私安全:
swift
import FoundationModels

let session = LanguageModelSession()
let response = try await session.respond(to: "总结:\(text)")

// 结构化输出
@Generable struct Summary { var title: String; var points: [String] }
let result: Summary = try await session.respond(to: prompt, generating: Summary.self)
如需了解工具调用、流式输出及会话管理,请查看
references/foundation-models.md

Testing

测试

swift
import Testing

@Suite("Project Tests")
struct ProjectTests {
    @Test("creates with defaults")
    func create() {
        let p = Project(name: "Test")
        #expect(p.name == "Test")
    }

    @Test("formats sizes", arguments: [(1024, "1 KB"), (0, "0 KB")])
    func format(bytes: Int, expected: String) {
        #expect(formatSize(bytes) == expected)
    }
}

// SwiftData testing
let container = try ModelContainer(
    for: Project.self,
    configurations: ModelConfiguration(isStoredInMemoryOnly: true)
)
let ctx = ModelContext(container)
ctx.insert(Project(name: "Test"))
try ctx.save()
For exit tests, attachments, UI testing, see
references/testing.md
.
swift
import Testing

@Suite("项目测试")
struct ProjectTests {
    @Test("使用默认值创建项目")
    func create() {
        let p = Project(name: "测试")
        #expect(p.name == "测试")
    }

    @Test("格式化文件大小", arguments: [(1024, "1 KB"), (0, "0 KB")])
    func format(bytes: Int, expected: String) {
        #expect(formatSize(bytes) == expected)
    }
}

// SwiftData测试
let container = try ModelContainer(
    for: Project.self,
    configurations: ModelConfiguration(isStoredInMemoryOnly: true)
)
let ctx = ModelContext(container)
ctx.insert(Project(name: "测试"))
try ctx.save()
如需了解退出测试、附件、UI测试,请查看
references/testing.md

Distribution

应用分发

MethodSandboxNotarizationReview
App StoreRequiredAutomaticYes
Developer IDRecommendedRequiredNo
Ad-HocNoNoLocal only
bash
xcodebuild archive -scheme MyApp -archivePath MyApp.xcarchive
xcodebuild -exportArchive -archivePath MyApp.xcarchive \
  -exportPath ./export -exportOptionsPlist ExportOptions.plist
xcrun notarytool submit ./export/MyApp.dmg \
  --apple-id you@example.com --team-id TEAM_ID \
  --password @keychain:AC_PASSWORD --wait
xcrun stapler staple ./export/MyApp.dmg
For complete distribution guide, see
references/distribution.md
.
方式沙箱公证审核
App Store必须自动
Developer ID推荐必须
临时分发仅本地可用
bash
xcodebuild archive -scheme MyApp -archivePath MyApp.xcarchive
xcodebuild -exportArchive -archivePath MyApp.xcarchive \
  -exportPath ./export -exportOptionsPlist ExportOptions.plist
xcrun notarytool submit ./export/MyApp.dmg \
  --apple-id you@example.com --team-id TEAM_ID \
  --password @keychain:AC_PASSWORD --wait
xcrun stapler staple ./export/MyApp.dmg
如需完整的分发指南,请查看
references/distribution.md

SPM

SPM

swift
// swift-tools-version: 6.2
let package = Package(
    name: "MyApp",
    platforms: [.macOS(.v14)],
    targets: [
        .executableTarget(name: "MyApp", swiftSettings: [
            .swiftLanguageMode(.v6),
            .defaultIsolation(MainActor.self),
        ]),
        .testTarget(name: "MyAppTests", dependencies: ["MyApp"]),
    ]
)
For build plugins, macros, and Swift Build, see
references/spm-build.md
.
swift
// swift-tools-version: 6.2
let package = Package(
    name: "MyApp",
    platforms: [.macOS(.v14)],
    targets: [
        .executableTarget(name: "MyApp", swiftSettings: [
            .swiftLanguageMode(.v6),
            .defaultIsolation(MainActor.self),
        ]),
        .testTarget(name: "MyAppTests", dependencies: ["MyApp"]),
    ]
)
如需了解构建插件、宏及Swift Build,请查看
references/spm-build.md

Liquid Glass (macOS 26)

Liquid Glass(macOS 26)

Apps rebuilt with Xcode 26 SDK get automatic Liquid Glass styling. Use
.glassEffect()
for custom glass surfaces,
GlassEffectContainer
for custom hierarchies. Opt out:
UIDesignRequiresLiquidGlass = NO
in Info.plist.
使用Xcode 26 SDK重建的应用将自动获得Liquid Glass样式。使用
.glassEffect()
创建自定义玻璃表面,
GlassEffectContainer
创建自定义层级结构。如需关闭:在Info.plist中设置
UIDesignRequiresLiquidGlass = NO

ScreenCaptureKit

ScreenCaptureKit

Capture screen content, app audio, and microphone (macOS 12.3+):
swift
import ScreenCaptureKit

let content = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)
guard let display = content.displays.first else { return }

// Filter: specific apps only
let filter = SCContentFilter(display: display, including: [targetApp], exceptingWindows: [])

// Configure
let config = SCStreamConfiguration()
config.capturesAudio = true
config.sampleRate = 48000
config.channelCount = 2
config.excludesCurrentProcessAudio = true

// Audio-only: minimize video overhead
config.width = 2; config.height = 2
config.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale.max)

let stream = SCStream(filter: filter, configuration: config, delegate: self)
try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: nil)
try stream.addStreamOutput(self, type: .audio, sampleHandlerQueue: audioQueue)
try await stream.startCapture()
macOS 15+:
SCRecordingOutput
for simplified file recording,
config.captureMicrophone
for mic capture. macOS 14+:
SCContentSharingPicker
for system picker UI,
SCScreenshotManager
for single-frame capture.
For complete API reference, audio writing (AVAssetWriter/AVAudioFile), permissions, and examples, see
references/screen-capture-audio.md
.
捕获屏幕内容、应用音频及麦克风(macOS 12.3+):
swift
import ScreenCaptureKit

let content = try await SCShareableContent.excludingDesktopWindows(false, onScreenWindowsOnly: true)
guard let display = content.displays.first else { return }

// 过滤:仅捕获特定应用
let filter = SCContentFilter(display: display, including: [targetApp], exceptingWindows: [])

// 配置
let config = SCStreamConfiguration()
config.capturesAudio = true
config.sampleRate = 48000
config.channelCount = 2
config.excludesCurrentProcessAudio = true

// 仅音频:最小化视频开销
config.width = 2; config.height = 2
config.minimumFrameInterval = CMTime(value: 1, timescale: CMTimeScale.max)

let stream = SCStream(filter: filter, configuration: config, delegate: self)
try stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: nil)
try stream.addStreamOutput(self, type: .audio, sampleHandlerQueue: audioQueue)
try await stream.startCapture()
macOS 15+:
SCRecordingOutput
用于简化文件录制,
config.captureMicrophone
用于捕获麦克风音频。macOS 14+:
SCContentSharingPicker
用于系统选择器UI,
SCScreenshotManager
用于单帧捕获。
如需完整的API参考、音频写入(AVAssetWriter/AVAudioFile)、权限及示例,请查看
references/screen-capture-audio.md

AppKit Interop

AppKit互操作

swift
struct WebViewWrapper: NSViewRepresentable {
    let url: URL
    func makeNSView(context: Context) -> WKWebView { WKWebView() }
    func updateNSView(_ v: WKWebView, context: Context) {
        v.load(URLRequest(url: url))
    }
}
For hosting SwiftUI in AppKit and advanced bridging, see
references/appkit-interop.md
.
swift
struct WebViewWrapper: NSViewRepresentable {
    let url: URL
    func makeNSView(context: Context) -> WKWebView { WKWebView() }
    func updateNSView(_ v: WKWebView, context: Context) {
        v.load(URLRequest(url: url))
    }
}
如需了解在AppKit中托管SwiftUI及高级桥接,请查看
references/appkit-interop.md

Architecture

架构

PatternBest ForComplexity
SwiftUI + @ObservableSmall-medium, soloLow
MVVM + @ObservableMedium, teamsMedium
TCALarge, strict testingHigh
See
references/architecture.md
for all patterns with examples.
模式适用场景复杂度
SwiftUI + @Observable中小型项目、个人开发
MVVM + @Observable中型项目、团队开发
TCA大型项目、严格测试要求
如需查看所有模式及示例,请查看
references/architecture.md

References

参考文档

FileWhen to read
SwiftUI & macOS
references/app-lifecycle.md
Window management, scenes, DocumentGroup, MenuBarExtra gotchas, async termination, LSUIElement issues
references/swiftui-macos.md
Sidebar, Inspector, Table, forms, popovers, sheets, search
references/appkit-interop.md
NSViewRepresentable, hosting controllers, AppKit bridging, NSPanel/floating HUD
references/screen-capture-audio.md
ScreenCaptureKit, SCStream gotchas, AVAudioEngine dual pipeline, AVAssetWriter crash safety, TCC gotchas
references/system-integration.md
Keyboard shortcuts, drag & drop, file access, App Intents, process monitoring, CoreAudio per-process APIs, login items, LSUIElement, idle sleep prevention
references/foundation-models.md
On-device AI: guided generation, tool calling, streaming
references/architecture.md
MVVM, TCA, dependency injection, project structure
references/testing.md
Swift Testing, exit tests, attachments, UI testing, XCTest migration
references/distribution.md
App Store, Developer ID, notarization gotchas, nested bundle signing, sandboxing, universal binaries
references/spm-build.md
Package.swift, Swift Build, plugins, macros, manual .app bundle assembly, mixed ObjC targets, CLT testing
Concurrency
references/approachable-concurrency.md
Default MainActor isolation, @concurrent, nonisolated async, runtime pitfalls
references/actors-isolation.md
Actor model, global actors, custom executors, reentrancy
references/structured-concurrency.md
Task, TaskGroup, async let, cancellation, priority, named tasks
references/sendable-safety.md
Sendable protocol, data race safety, @unchecked Sendable + serial queue, @preconcurrency import
references/async-patterns.md
AsyncSequence, AsyncStream, Observations, continuations, Clock
references/migration-guide.md
GCD to async/await, Combine to AsyncSequence, Swift 6 migration
SwiftData
references/models-schema.md
@Model, @Attribute options, Codable, transformable, external storage
references/relationships-predicates.md
Advanced relationships, inverse rules, compound predicates
references/container-context.md
ModelContainer, ModelContext, background contexts, undo/redo, batch ops
references/cloudkit-sync.md
CloudKit setup, conflict resolution, sharing, debugging sync
references/migrations.md
VersionedSchema, lightweight/custom migration, Core Data migration
文件阅读场景
SwiftUI & macOS
references/app-lifecycle.md
窗口管理、场景、DocumentGroup、MenuBarExtra注意事项、异步终止、LSUIElement问题
references/swiftui-macos.md
侧边栏、检查器、表格、表单、弹出框、面板、搜索
references/appkit-interop.md
NSViewRepresentable、托管控制器、AppKit桥接、NSPanel/浮动HUD
references/screen-capture-audio.md
ScreenCaptureKit、SCStream注意事项、AVAudioEngine双管道、AVAssetWriter崩溃安全、TCA注意事项
references/system-integration.md
键盘快捷键、拖放、文件访问、App Intents、进程监控、CoreAudio进程级API、登录项、LSUIElement、防止睡眠
references/foundation-models.md
本地AI:引导生成、工具调用、流式输出
references/architecture.md
MVVM、TCA、依赖注入、项目结构
references/testing.md
Swift Testing、退出测试、附件、UI测试、XCTest迁移
references/distribution.md
App Store、Developer ID、公证注意事项、嵌套包签名、沙箱、通用二进制
references/spm-build.md
Package.swift、Swift Build、插件、宏、手动.app包组装、混合ObjC目标、CLT测试
并发编程
references/approachable-concurrency.md
默认MainActor隔离、@concurrent、非隔离异步、运行时陷阱
references/actors-isolation.md
Actor模型、全局Actor、自定义执行器、重入
references/structured-concurrency.md
Task、TaskGroup、async let、取消、优先级、命名任务
references/sendable-safety.md
Sendable协议、数据竞争安全、@unchecked Sendable + 串行队列、@preconcurrency导入
references/async-patterns.md
AsyncSequence、AsyncStream、Observations、延续、Clock
references/migration-guide.md
GCD迁移到async/await、Combine迁移到AsyncSequence、Swift 6迁移
SwiftData
references/models-schema.md
@Model、@Attribute选项、Codable、可转换、外部存储
references/relationships-predicates.md
高级关联关系、反向规则、复合谓词
references/container-context.md
ModelContainer、ModelContext、后台上下文、撤销/重做、批量操作
references/cloudkit-sync.md
CloudKit设置、冲突解决、共享、同步调试
references/migrations.md
VersionedSchema、轻量/自定义迁移、Core Data迁移