Swift最佳实践技能 swift-best-practices

这个技能用于编写和审查Swift代码,特别是针对iOS和macOS平台的应用开发,遵循Swift 6+最佳实践,包括并发安全、API设计和代码质量优化。它覆盖async/await、actors、MainActor等现代特性,并提供迁移策略和指南。关键词:Swift开发, 并发编程, async/await, iOS开发, macOS开发, 代码审查, API设计, 迁移策略

移动开发 0 次安装 0 次浏览 更新于 3/7/2026

name: swift-best-practices description: | 此技能应在为iOS或macOS项目编写或审查Swift代码时使用。应用现代Swift 6+最佳实践、并发模式、API设计指南和迁移策略。涵盖async/await、actors、MainActor、Sendable、类型化throws和Swift 6破坏性更改。

关键词:并发, async-await, actors, Sendable, typed-throws, Swift-6, 迁移, 数据竞争, MainActor, nonisolated, isolated, iOS, macOS, SwiftUI, Combine, Swift-concurrency, actor-isolation, strict-concurrency, Swift-migration, modern-Swift, Swift-evolution, 代码审查, Swift-patterns, Apple-platforms, Xcode, iOS-development, macOS-development license: MIT allowed-tools: [Read, Write, Edit, Bash, Grep, Glob] metadata: version: 1.0.0 swift_version: “6.0+” platform: “macOS 15.7+, iOS 18+” production_tested: true companion_mcp: “swiftlens” mcp_install: “uvx swiftlens” references_source: “sammcj/agentic-coding (Apache 2.0)”

Swift 最佳实践技能

概述

应用现代Swift开发最佳实践,专注于Swift 6+特性、并发安全、API设计原则和代码质量指南,适用于针对macOS 15.7+的iOS和macOS项目。

何时使用此技能

使用此技能当:

  • 为iOS或macOS应用程序编写新的Swift代码
  • 审查Swift代码的正确性、安全性和风格
  • 实现Swift并发特性(async/await、actors、MainActor)
  • 设计Swift API和公共接口
  • 将代码从Swift 5迁移到Swift 6
  • 解决并发警告、数据竞争问题或与Sendable/隔离相关的编译器错误
  • 使用Swift 6和6.2中引入的现代Swift语言特性

SwiftLens MCP集成(Claude Code)

此技能补充SwiftLens MCP服务器,用于语义级Swift代码分析。

SwiftLens提供:

  • 15个工具,使用Apple的SourceKit-LSP进行语义Swift分析
  • 符号查找、跨文件引用、类型信息
  • 安全代码修改和重构
  • 编译器级对Swift代码结构的理解

此技能提供:

  • Swift 6+设计模式和最佳实践
  • 并发策略(async/await、actors、MainActor)
  • API设计指南和命名约定
  • 迁移指导(Swift 5 → Swift 6)

Claude Code CLI设置:

在Swift项目中创建.claude/mcps/swiftlens.json

{
  "mcpServers": {
    "swiftlens": {
      "description": "SwiftLens MCP通过SourceKit-LSP提供语义Swift分析",
      "command": "uvx",
      "args": ["swiftlens"]
    }
  }
}

⚠️ 注意: 这是Claude Code配置(非Claude Desktop)。请参阅references/swiftlens-mcp-claude-code.md获取完整设置指南、所有15个工具、索引构建和使用示例。

工作流程: SwiftLens提供运行时分析(代码在做什么),此技能提供设计专业知识(代码应该做什么)。

核心指南

基本原则

  1. 使用点的清晰性至关重要 - 通过检查使用案例评估设计,而不仅仅是声明
  2. 清晰优于简洁 - 紧凑代码来自类型系统,而非最少字符
  3. 为每个公共声明编写文档 - 如果无法简单描述功能,API可能设计不佳
  4. 按角色命名,而非类型 - var greeting = "Hello" 而不是 var string = "Hello"
  5. 偏爱通过简单实现的优雅 - 避免过度工程,除非复杂性真正需要

Swift 6 并发模型

Swift 6默认启用完整的并发检查,基于区域隔离(SE-0414)。编译器现在证明代码安全性,消除许多误报,同时在编译时捕获真正的并发问题。

关键理解:

  • 异步 ≠ 后台 - 异步函数可以暂停,但不自动在后台线程运行
  • 演员通过自动同步保护可变共享状态
  • @MainActor 确保UI相关代码在主线程执行
  • 全局演员隔离类型自动为 Sendable

基本模式

Async/Await

// 使用async let进行并行执行
func fetchData() async -> (String, Int) {
    async let stringData = fetchString()
    async let intData = fetchInt()
    return await (stringData, intData)
}

// 在长时间操作中始终检查取消
func process(_ items: [Item]) async throws -> [Result] {
    var results: [Result] = []
    for item in items {
        try Task.checkCancellation()
        results.append(await process(item))
    }
    return results
}

MainActor 用于 UI 代码

// 在类型级别应用以实现一致隔离
@MainActor
class ContentViewModel: ObservableObject {
    @Published var images: [UIImage] = []

    func fetchData() async throws {
        self.images = try await fetchImages()
    }
}

// 当直接await可行时避免MainActor.run
await doMainActorStuff()  // 好
await MainActor.run { doMainActorStuff() }  // 不必要

Actor 隔离

actor DataCache {
    private var cache: [String: Data] = [:]

    func store(_ data: Data, forKey key: String) {
        cache[key] = data  // 在actor内部无需await
    }

    nonisolated func cacheType() -> String {
        return "DataCache"  // 无需await - 不访问隔离状态
    }
}

常见陷阱以避免

  1. 不要不必要地将函数标记为 async - 异步调用约定有开销
  2. 切勿将 DispatchSemaphore 与 async/await 一起使用 - 可能导致死锁
  3. 不要创建无状态演员 - 使用非隔离异步函数代替
  4. 避免分裂隔离 - 不要在一个类型内混合隔离域
  5. 检查任务取消 - 长时间操作必须检查 Task.checkCancellation()
  6. 不要假设异步意味着后台 - 如果需要在后台移动工作,请显式执行
  7. 避免过度上下文切换 - 在同一隔离域内分组操作

API 设计快速参考

命名约定

  • 类型/协议:UpperCamelCase
  • 其他所有:lowerCamelCase
  • 描述能力的协议:-able-ible-ing 后缀(如 EquatableProgressReporting
  • 工厂方法:以 make 开头(如 x.makeIterator()
  • 变体对:命令式与过去分词(如 x.sort() / x.sorted()

按副作用命名方法

  • 无副作用:名词短语(如 x.distance(to: y)
  • 有副作用:命令式动词(如 x.append(y)x.sort()

参数标签

  • 当参数无法区分时省略:min(number1, number2)
  • 值保持转换省略第一个标签:Int64(someUInt32)
  • 介词短语在介词处标签:x.removeBoxes(havingLength: 12)
  • 标签所有其他参数

Swift 6 破坏性更改

必须用 @MainActor 显式标记类型(SE-0401)

属性包装器不再自动推断演员隔离。

@MainActor
struct LogInView: View {
    @StateObject private var model = ViewModel()
}

全局变量必须是并发安全的(SE-0412)

static let config = Config()  // 常量 - 好
@MainActor static var state = State()  // 演员隔离 - 好
nonisolated(unsafe) var cache = [String: Data]()  // 不安全 - 谨慎使用

其他更改

  • @UIApplicationMain/@NSApplicationMain 已弃用(使用 @main
  • 存在类型需要使用 any
  • 导入可见性需要显式访问控制

API 可用性模式

// 基本可用性
@available(macOS 15, iOS 18, *)
func modernAPI() { }

// 带消息的弃用
@available(*, deprecated, message: "使用 newMethod() 代替")
func oldMethod() { }

// 带自动修复的重命名
@available(*, unavailable, renamed: "newMethod")
func oldMethod() { }

// 运行时检查
if #available(iOS 18, *) {
    // iOS 18+ 代码
}

// 反向检查(Swift 5.6+)
if #unavailable(iOS 18, *) {
    // iOS 17 及更低
}

关键区别:

  • deprecated - 警告,允许使用
  • obsoleted - 从特定版本起错误
  • unavailable - 错误,完全阻止使用

如何使用此技能

编写代码时

  1. 应用基于角色、清晰优先的命名约定
  2. 使用适当的隔离(UI用 @MainActor,可变状态用演员)
  3. 正确实现async/await模式,正确处理取消
  4. 遵循Swift 6并发模型 - 信任编译器的流分析
  5. 用清晰、简洁的摘要记录公共API

审查代码时

  1. 检查并发安全违规
  2. 验证适当的演员隔离和Sendable一致性
  3. 确保异步函数适当处理取消
  4. 验证API命名遵循Swift指南
  5. 确认可用性注解对目标平台正确

代码质量标准

  • 最小化注释 - 代码应尽可能自文档化
  • 避免过度工程和不必要的抽象
  • 使用基于角色的有意义变量名,而非类型
  • 遵循既定项目架构和模式
  • 优先使用 count(where:) 而非 filter().count
  • 对于固定大小、性能关键数据,使用 InlineArray
  • 信任编译器的并发流分析 - 避免不必要的 Sendable 一致性

资源

references/

当需要深入信息时加载的详细参考材料:

  • swiftlens-mcp-claude-code.md - SwiftLens MCP服务器设置,适用于Claude Code CLI,15个语义分析工具,索引构建,使用示例和集成工作流程
  • api-design.md - 完整的API设计约定、文档标准、参数指南和命名模式
  • concurrency.md - 详细的async/await模式、演员最佳实践、常见陷阱、性能考虑和线程安全模式
  • swift6-features.md - Swift 6/6.2中的新语言特性、破坏性更改、迁移策略和现代模式
  • availability-patterns.md - 全面的 @available 属性使用、弃用策略和平台版本管理

当需要超出上述核心指南的详细信息时,加载这些参考。

平台要求

  • Swift 6.0+ 编译器以使用Swift 6特性
  • Swift 6.2+ 以使用InlineArray和增强的并发特性
  • macOS 15.7+ 带适当SDK
  • iOS 18+ 以使用最新平台特性
  • 使用 #available 进行运行时平台检测
  • 使用 @available 进行API可用性标记