iOS/Swift 核心开发
Swift 编码规范
命名规则
- •类型名 UpperCamelCase:
class NetworkManager,struct UserProfile - •变量/函数 lowerCamelCase:
var isLoading,func fetchUser() - •Bool 属性用
is/has/should/can前缀:isEnabled,hasPermission - •Protocol 描述能力用
-able/-ing:Codable,DataProviding;描述角色用名词:Delegate - •缩写: 首位全小写
urlString;非首位两字母全大写userID,三字母以上首字母大写userUrl
类型选择
- •默认用 struct,需要引用语义/继承/deinit/ObjC 互操作才用 class
- •穷举状态用 enum + associated value:
case loaded(Data),case failed(Error) - •常量命名空间用无 case 的 enum:
enum Constants { static let timeout = 30.0 }
访问控制
- •默认最严格:
private>fileprivate>internal>public>open - •对外 API 显式标注
public - •ViewModel 的
@Published属性用private(set) - •SwiftUI 的
@State必须标记为private
错误处理
- •定义领域错误 enum 遵循
LocalizedError,实现errorDescription - •用
throws传播错误,避免静默失败 - •禁止生产代码中
try!/as!/!,除非有绝对安全理由并写注释
并发 (async/await)
- •优先 async/await 而非回调或 Combine
- •并行独立任务用
async let - •UI 更新必须在
@MainActor - •共享可变状态用
actor保护 - •ViewModel 类标注
@MainActor - •SwiftUI View 中用
.task启动异步任务,自动取消
闭包
- •始终用
[weak self],然后guard let self else { return } - •确定被引用对象生命周期更长才用
[unowned self]
代码组织
- •用
// MARK: - Section分区 - •Protocol 实现放 extension
- •函数不超过 40 行,文件不超过 400 行
- •用
guard提前返回,最多 3 层缩进 - •SwiftUI View body 不超过 40 行,复杂部分提取为 computed property 或子 View
注释
- •公开 API 用
///文档注释,含参数/返回值/异常说明 - •注释解释 why,代码本身解释 what
- •删除被注释掉的代码
项目结构
默认目录布局
code
App/ → AppDelegate, SceneDelegate, 启动配置 Core/ → 基础设施 (Network, Storage, Extensions, Utilities) Features/<FeatureName>/ → 功能模块 (Views, ViewModels, Models, Services) UI/Components/ → 可复用 UI 组件 Resources/ → Assets, Localizable, Info.plist
架构选择
- •SwiftUI 默认: View + ViewModel (@Observable) + Model + Service
- •UIKit 默认: MVVM + Coordinator(中型以上项目)
- •复杂 SDK/大型项目用 Clean Architecture: Domain → Data → Presentation
依赖注入
- •通过 init 注入,不直接引用单例
- •定义 Protocol 抽象,注入协议类型
- •SwiftUI 用
@Environment或 custom EnvironmentKey - •UIKit 通过 Coordinator 或 init 注入
模块化
- •用 SPM 拆分本地模块
- •Core 模块零外部依赖
- •Feature 模块依赖 Core,不互相依赖
- •每个模块有独立 Tests target
文件规则
- •一文件一主类型,文件名与类型名一致
- •Extension 文件:
String+Validation.swift - •测试文件:
UserServiceTests.swift
SwiftUI 核心规则
状态管理
- •优先
@Observable而非ObservableObject(iOS 17+) - •
@State必须标记private,用于 View 拥有的状态 - •
@State+@Observableclass 替代@StateObject - •
@Binding仅用于子视图需要修改父状态 - •
@Bindable用于注入的@Observable对象需要绑定时 - •只读值用
let,不要用@State或@Binding - •
@Observable类必须标注@MainActor
现代 API(必须使用)
- •
foregroundStyle()而非foregroundColor() - •
clipShape(.rect(cornerRadius:))而非cornerRadius() - •
NavigationStack而非NavigationView - •
navigationDestination(for:)实现类型安全导航 - •
TabAPI(iOS 18+)而非tabItem() - •
.onChange(of:) { old, new in }双参数版本 - •
.task而非.onAppear启动异步任务 - •
Button而非onTapGesture(除非需要位置/次数)
性能优化
- •只传递 View 需要的具体值,避免传整个大对象
- •避免热路径中的冗余状态更新(检查值变化再赋值)
- •ForEach 必须用稳定 ID,禁止
.indices(动态内容) - •大列表用
LazyVStack/LazyHStack - •避免在 ForEach 中内联过滤,预先过滤并缓存
- •View body 保持纯净,无副作用或复杂逻辑
动画
- •用
.animation(_:value:)而非已废弃的.animation(_:) - •按钮点击用
withAnimation - •动画修饰符放在被动画属性之后
- •过渡用
.transition()+withAnimation
UIKit 核心规则
ViewController 结构
按顺序组织:Properties → UI Components → Lifecycle → Setup → Methods → Actions → Protocol Extensions
布局
- •优先 SnapKit(如可用)或
NSLayoutConstraint.activate([]) - •优先
UIStackView减少约束 - •复杂列表用
UICollectionViewCompositionalLayout+DiffableDataSource
内存管理
- •Delegate 必须
weak - •闭包捕获
[weak self] - •Timer/观察者在 deinit 中清理
专项参考
深入学习特定主题时,查阅以下详细指南:
- •SwiftUI 开发 - 状态管理、现代 API、列表性能、动画、布局最佳实践
- •UIKit 开发 - ViewController 结构、布局、Cell 复用、自定义控件
- •导航架构 - Coordinator Pattern(UIKit)、NavigationStack + Router(SwiftUI)、深度链接
- •动画系统 - SwiftUI 动画(隐式/显式/过渡)、UIKit 动画、性能优化
- •性能优化 - SwiftUI 热路径优化、UIKit 视图层级优化、内存管理
- •组件设计 - 自定义组件、可配置 API、可复用模式
- •内存管理 - 循环引用、泄漏预防、weak/unowned 使用
✅ Sentinel(Skill 使用自检)
当且仅当你确定本 Skill 已被加载并用于当前任务时,在回复末尾追加:
// skill-used: ios-base
规则:
- •只能输出一次
- •如果不确定是否加载,禁止输出 sentinel
- •输出 sentinel 代表你已遵守本 Skill 的硬性规则与交付格式
- •只有当任务与本 skill 的 description 明显匹配时才允许输出 sentinel