关于 swift-best-practices
面向 iOS 和 macOS Swift 开发与代码审查的技能,提供 Swift 6 并发、API 设计及 Swift 5 迁移指引,并与 SwiftLens MCP 的语义分析相辅相成。
主要功能
- 01Swift 6 并发与隔离指导
- 02API 设计与命名规范
- 03Swift 5 到 Swift 6 迁移
- 04代码审查与安全检查
- 05平台可用性标注指导
适用场景
- 01编写 iOS 或 macOS Swift 代码
- 02排查并发与数据竞争问题
- 03审查公共 API 设计
- 04迁移 Swift 5 项目
MCP 相关
与 SwiftLens MCP 服务配合使用:SwiftLens 提供基于 SourceKit-LSP 的语义代码分析,本技能提供设计与并发实践指引。文档还说明了在 Claude Code CLI 中配置该服务的方法。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ secondsky/ claude-skills --skill swift-best-practices安装后在 Claude Code 中输入/swift-best-practices确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-design.mdavailability-patterns.mdconcurrency.mdswift6-features.mdswiftlens-mcp-claude-code.mdtemplates/actor-pattern.swiftapi-design-example.swiftasync-await-migration.swiftmainactor-viewmodel.swiftREADME.md详细介绍
Swift 最佳实践技能
概述
针对目标平台为 macOS 15.7+ 的 iOS 和 macOS 项目,应用现代 Swift 开发最佳实践,重点关注 Swift 6+ 功能、并发安全性、API 设计原则和代码质量指南。
何时使用此技能
在以下情况下使用此技能:
- 为 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 提供:
- 使用 Apple 的 SourceKit-LSP 进行语义 Swift 分析的 15 个工具
- 符号查找、跨文件引用、类型信息
- 安全的代码修改和重构
- 对 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 provides semantic Swift analysis via SourceKit-LSP",
"command": "uvx",
"args": ["swiftlens"]
}
}
}
⚠️ 注意:这是 Claude Code 配置(不是 Claude Desktop)。完整设置指南、全部 15 个工具、索引构建和使用示例,请参阅 references/swiftlens-mcp-claude-code.md。
工作流:SwiftLens 提供运行时分析(代码正在做什么),此技能提供设计专业知识(代码应该做什么)。
核心指南
基本原则
- 使用位置的清晰性至关重要——应通过检查用例而不只是声明来评估设计
- 清晰胜于简洁——紧凑的代码应源自类型系统,而不是尽量减少字符
- 为每个公共声明编写文档——如果无法简单地描述其功能,API 的设计可能不佳
- 按角色而非类型命名——使用
var greeting = "Hello",而不是var string = "Hello" - 以简洁实现优雅——除非确有必要,否则避免过度设计
Swift 6 并发模型
Swift 6 默认启用完整的并发检查,并采用基于区域的隔离(SE-0414)。编译器现在能够证明代码的安全性,在编译时消除许多误报并捕获真正的并发问题。
关键认知:
- 异步 ≠ 后台——异步函数可以暂停,但不会自动在后台线程上运行
- Actors 通过自动同步保护可变共享状态
@MainActor确保与 UI 相关的代码在主线程上执行- 全局 Actor 隔离类型会自动符合
Sendable
基本模式
Async/Await
// Parallel execution with async let
func fetchData() async -> (String, Int) {
async let stringData = fetchString()
async let intData = fetchInt()
return await (stringData, intData)
}
// Always check cancellation in long-running operations
func process(_ items: [Item]) async throws -> [Result] {
var results: [Result] = []
for item in items {
try Task.checkCancellation()
results.append(await process(item))
}
return results
}
用于 UI 代码的 MainActor
// Apply at type level for consistent isolation
@MainActor
class ContentViewModel: ObservableObject {
@Published var images: [UIImage] = []
func fetchData() async throws {
self.images = try await fetchImages()
}
}
// Avoid MainActor.run when direct await works
await doMainActorStuff() // Good
await MainActor.run { doMainActorStuff() } // Unnecessary
Actor 隔离
actor DataCache {
private var cache: [String: Data] = [:]
func store(_ data: Data, forKey key: String) {
cache[key] = data // No await needed inside actor
}
nonisolated func cacheType() -> String {
return "DataCache" // No await needed - doesn't access isolated state
}
}
应避免的常见陷阱
- 不要不必要地将函数标记为
async——异步调用约定会带来开销 - 切勿在 async/await 中使用
DispatchSemaphore——有死锁风险 - 不要创建无状态 actors——改用非隔离异步函数
- 避免拆分隔离——不要在同一类型中混用隔离域
- 检查任务取消状态——长时间运行的操作必须检查
Task.checkCancellation() - 不要认为 async 就意味着后台运行——如有需要,应明确将工作移至后台
- 避免过度切换上下文——在同一隔离域内集中执行操作
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() // Constant - OK
@MainActor static var state = State() // Actor-isolated - OK
nonisolated(unsafe) var cache = [String: Data]() // Unsafe - use with caution
其他变更
@UIApplicationMain/@NSApplicationMain已弃用(请使用@main)- 存在类型必须使用
any - 导入可见性需要显式访问控制
API 可用性模式
// Basic availability
@available(macOS 15, iOS 18, *)
func modernAPI() { }
// Deprecation with message
@available(*, deprecated, message: "Use newMethod() instead")
func oldMethod() { }
// Renaming with auto-fix
@available(*, unavailable, renamed: "newMethod")
func oldMethod() { }
// Runtime checking
if #available(iOS 18, *) {
// iOS 18+ code
}
// Inverted checking (Swift 5.6+)
if #unavailable(iOS 18, *) {
// iOS 17 and lower
}
主要区别:
deprecated- 发出警告,但允许使用obsoleted- 从指定版本起报错unavailable- 报错,完全禁止使用
如何使用此技能
编写代码时
- 遵循以角色为导向、清晰优先的原则应用命名约定
- 使用适当的隔离方式(UI 使用
@MainActor,可变状态使用 Actor) - 正确实现 async/await 模式,并妥善处理取消
- 遵循 Swift 6 并发模型,信任编译器的流程分析
- 为公共 API 编写清晰、简洁的摘要文档
审查代码时
- 检查是否违反并发安全要求
- 验证 Actor 隔离和 Sendable 一致性是否正确
- 确保异步函数妥善处理取消
- 检查 API 命名是否遵循 Swift 指南
- 确认可用性注解是否适用于目标平台
代码质量标准
- 尽量减少注释;代码应尽可能做到自解释
- 避免过度设计和不必要的抽象
- 根据变量的角色而非类型使用有意义的名称
- 遵循既定的项目架构和模式
- 优先使用
count(where:),而不是filter().count - 对固定大小且对性能要求较高的数据使用
InlineArray - 信任编译器的并发流程分析,避免不必要的
Sendable一致性声明
资源
references/
需要深入了解时可加载的详细参考资料:
- swiftlens-mcp-claude-code.md - Claude Code CLI 的 SwiftLens MCP 服务设置、15 种语义分析工具、索引构建、使用示例和集成工作流
- api-design.md - 完整的 API 设计约定、文档标准、参数指南和命名模式
- concurrency.md - 详细的 async/await 模式、Actor 最佳实践、常见问题、性能考量和线程安全模式
- 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 可用性