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提供运行时分析(代码在做什么),此技能提供设计专业知识(代码应该做什么)。
核心指南
基本原则
- 使用点的清晰性至关重要 - 通过检查使用案例评估设计,而不仅仅是声明
- 清晰优于简洁 - 紧凑代码来自类型系统,而非最少字符
- 为每个公共声明编写文档 - 如果无法简单描述功能,API可能设计不佳
- 按角色命名,而非类型 -
var greeting = "Hello"而不是var string = "Hello" - 偏爱通过简单实现的优雅 - 避免过度工程,除非复杂性真正需要
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 - 不访问隔离状态
}
}
常见陷阱以避免
- 不要不必要地将函数标记为
async- 异步调用约定有开销 - 切勿将
DispatchSemaphore与 async/await 一起使用 - 可能导致死锁 - 不要创建无状态演员 - 使用非隔离异步函数代替
- 避免分裂隔离 - 不要在一个类型内混合隔离域
- 检查任务取消 - 长时间操作必须检查
Task.checkCancellation() - 不要假设异步意味着后台 - 如果需要在后台移动工作,请显式执行
- 避免过度上下文切换 - 在同一隔离域内分组操作
API 设计快速参考
命名约定
- 类型/协议:
UpperCamelCase - 其他所有:
lowerCamelCase - 描述能力的协议:
-able、-ible、-ing后缀(如Equatable、ProgressReporting) - 工厂方法:以
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- 错误,完全阻止使用
如何使用此技能
编写代码时
- 应用基于角色、清晰优先的命名约定
- 使用适当的隔离(UI用
@MainActor,可变状态用演员) - 正确实现async/await模式,正确处理取消
- 遵循Swift 6并发模型 - 信任编译器的流分析
- 用清晰、简洁的摘要记录公共API
审查代码时
- 检查并发安全违规
- 验证适当的演员隔离和Sendable一致性
- 确保异步函数适当处理取消
- 验证API命名遵循Swift指南
- 确认可用性注解对目标平台正确
代码质量标准
- 最小化注释 - 代码应尽可能自文档化
- 避免过度工程和不必要的抽象
- 使用基于角色的有意义变量名,而非类型
- 遵循既定项目架构和模式
- 优先使用
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可用性标记