ios-base
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseiOS/Swift 核心开发
Core iOS/Swift Development
Swift 编码规范
Swift Coding Specifications
命名规则
Naming Rules
- 类型名 UpperCamelCase: ,
class NetworkManagerstruct UserProfile - 变量/函数 lowerCamelCase: ,
var isLoadingfunc fetchUser() - Bool 属性用 /
is/has/should前缀:can,isEnabledhasPermission - Protocol 描述能力用 /
-able:-ing,Codable;描述角色用名词:DataProvidingDelegate - 缩写: 首位全小写 ;非首位两字母全大写
urlString,三字母以上首字母大写userIDuserUrl
- Type names use UpperCamelCase: ,
class NetworkManagerstruct UserProfile - Variables/functions use lowerCamelCase: ,
var isLoadingfunc fetchUser() - Bool properties use /
is/has/shouldprefix:can,isEnabledhasPermission - Protocols describing capabilities use /
-ablesuffix:-ing,Codable; Protocols describing roles use nouns:DataProvidingDelegate - Abbreviations: All lowercase if at the start ; Two-letter abbreviations are all uppercase if not at the start
urlString, abbreviations longer than 3 letters capitalize only the first letteruserIDuserUrl
类型选择
Type Selection
- 默认用 struct,需要引用语义/继承/deinit/ObjC 互操作才用 class
- 穷举状态用 enum + associated value: ,
case loaded(Data)case failed(Error) - 常量命名空间用无 case 的 enum:
enum Constants { static let timeout = 30.0 }
- Use struct by default, use class only when reference semantics/inheritance/deinit/ObjC interoperability is required
- Use enum + associated value for exhaustive states: ,
case loaded(Data)case failed(Error) - Use enum with no cases for constant namespace:
enum Constants { static let timeout = 30.0 }
访问控制
Access Control
- 默认最严格: >
private>fileprivate>internal>publicopen - 对外 API 显式标注
public - ViewModel 的 属性用
@Publishedprivate(set) - SwiftUI 的 必须标记为
@Stateprivate
- Use the strictest level by default: >
private>fileprivate>internal>publicopen - Explicitly mark external APIs with
public - Use for
private(set)properties in ViewModel@Published - SwiftUI must be marked as
@Stateprivate
错误处理
Error Handling
- 定义领域错误 enum 遵循 ,实现
LocalizedErrorerrorDescription - 用 传播错误,避免静默失败
throws - 禁止生产代码中 /
try!/as!,除非有绝对安全理由并写注释!
- Define domain error enum that conforms to , implement
LocalizedErrorerrorDescription - Use to propagate errors, avoid silent failures
throws - Forbid /
try!/as!in production code, unless there is an absolutely safe reason and a comment is added!
并发 (async/await)
Concurrency (async/await)
- 优先 async/await 而非回调或 Combine
- 并行独立任务用
async let - UI 更新必须在
@MainActor - 简单共享状态保持单一写入源;复杂隔离策略交由
swift-expert - ViewModel 类标注
@MainActor - SwiftUI View 中用 启动异步任务,自动取消
.task
- Prioritize async/await over callbacks or Combine
- Use for parallel independent tasks
async let - UI updates must be executed on
@MainActor - Maintain a single write source for simple shared states; hand over complex isolation strategies to
swift-expert - Mark ViewModel classes with
@MainActor - Use to start asynchronous tasks in SwiftUI View, which will be canceled automatically
.task
闭包
Closures
- 始终用 ,然后
[weak self]guard let self else { return } - 确定被引用对象生命周期更长才用
[unowned self]
- Always use , then
[weak self]guard let self else { return } - Use only when you confirm the referenced object has a longer lifecycle
[unowned self]
代码组织
Code Organization
- 用 分区
// MARK: - Section - Protocol 实现放 extension
- 函数不超过 40 行,文件不超过 400 行
- 用 提前返回,最多 3 层缩进
guard - SwiftUI View body 不超过 40 行,复杂部分提取为 computed property 或子 View
- Use to partition code
// MARK: - Section - Put Protocol implementations in extensions
- Functions should not exceed 40 lines, files should not exceed 400 lines
- Use for early return, maximum 3 levels of indentation
guard - SwiftUI View body should not exceed 40 lines, extract complex parts as computed properties or sub Views
注释
Comments
- 公开 API 用 文档注释,含参数/返回值/异常说明
/// - 注释解释 why,代码本身解释 what
- 删除被注释掉的代码
- Use document comments for public APIs, including parameter/return value/exception descriptions
/// - Comments explain why, the code itself explains what
- Delete commented out code
项目结构
Project Structure
默认目录布局
Default Directory Layout
App/ → AppDelegate, SceneDelegate, 启动配置
Core/ → 基础设施 (Network, Storage, Extensions, Utilities)
Features/<FeatureName>/ → 功能模块 (Views, ViewModels, Models, Services)
UI/Components/ → 可复用 UI 组件
Resources/ → Assets, Localizable, Info.plistApp/ → AppDelegate, SceneDelegate, startup configuration
Core/ → Infrastructure (Network, Storage, Extensions, Utilities)
Features/<FeatureName>/ → Feature modules (Views, ViewModels, Models, Services)
UI/Components/ → Reusable UI components
Resources/ → Assets, Localizable, Info.plist架构选择
Architecture Selection
- SwiftUI 默认: View + ViewModel (@Observable) + Model + Service
- UIKit 默认: MVVM + Coordinator(中型以上项目)
- 复杂 SDK/大型项目用 Clean Architecture: Domain → Data → Presentation
- Default for SwiftUI: View + ViewModel (@Observable) + Model + Service
- Default for UIKit: MVVM + Coordinator (for medium and above projects)
- Use Clean Architecture for complex SDK/large projects: Domain → Data → Presentation
依赖注入
Dependency Injection
- 通过 init 注入,不直接引用单例
- 定义 Protocol 抽象,注入协议类型
- SwiftUI 用 或 custom EnvironmentKey
@Environment - UIKit 通过 Coordinator 或 init 注入
- Inject through init, do not reference singletons directly
- Define Protocol abstraction, inject protocol types
- Use or custom EnvironmentKey for SwiftUI
@Environment - Inject through Coordinator or init for UIKit
模块化
Modularization
- 用 SPM 拆分本地模块
- Core 模块零外部依赖
- Feature 模块依赖 Core,不互相依赖
- 每个模块有独立 Tests target
- Split local modules with SPM
- Core module has zero external dependencies
- Feature modules depend on Core, do not depend on each other
- Each module has an independent Tests target
文件规则
File Rules
- 一文件一主类型,文件名与类型名一致
- Extension 文件:
String+Validation.swift - 测试文件:
UserServiceTests.swift
- One main type per file, file name matches the type name
- Extension files:
String+Validation.swift - Test files:
UserServiceTests.swift
SwiftUI 核心规则
SwiftUI Core Rules
状态管理
State Management
- 优先 而非
@Observable(iOS 17+)ObservableObject - 必须标记
@State,用于 View 拥有的状态private - +
@Stateclass 替代@Observable@StateObject - 仅用于子视图需要修改父状态
@Binding - 用于注入的
@Bindable对象需要绑定时@Observable - 只读值用 ,不要用
let或@State@Binding - 类必须标注
@Observable@MainActor
- Prioritize over
@Observable(iOS 17+)ObservableObject - must be marked
@State, used for states owned by the Viewprivate - +
@Stateclass replaces@Observable@StateObject - is only used when the child view needs to modify the parent state
@Binding - is used when the injected
@Bindableobject needs to be bound@Observable - Use for read-only values, do not use
letor@State@Binding - classes must be marked with
@Observable@MainActor
现代 API(必须使用)
Modern APIs (Mandatory Usage)
- 而非
foregroundStyle()foregroundColor() - 而非
clipShape(.rect(cornerRadius:))cornerRadius() - 而非
NavigationStackNavigationView - 实现类型安全导航
navigationDestination(for:) - API(iOS 18+)而非
TabtabItem() - 双参数版本
.onChange(of:) { old, new in } - 而非
.task启动异步任务.onAppear - 而非
Button(除非需要位置/次数)onTapGesture
- instead of
foregroundStyle()foregroundColor() - instead of
clipShape(.rect(cornerRadius:))cornerRadius() - instead of
NavigationStackNavigationView - Implement type-safe navigation with
navigationDestination(for:) - API (iOS 18+) instead of
TabtabItem() - Dual parameter version of
.onChange(of:) { old, new in } - Use instead of
.taskto start asynchronous tasks.onAppear - Use instead of
Button(unless position/click count is needed)onTapGesture
性能优化
Performance Optimization
- 只传递 View 需要的具体值,避免传整个大对象
- 避免热路径中的冗余状态更新(检查值变化再赋值)
- ForEach 必须用稳定 ID,禁止 (动态内容)
.indices - 大列表用 /
LazyVStackLazyHStack - 避免在 ForEach 中内联过滤,预先过滤并缓存
- View body 保持纯净,无副作用或复杂逻辑
- 复杂性能剖析(热路径量化、复制开销建模)交由
swift-expert
- Only pass specific values needed by the View, avoid passing the entire large object
- Avoid redundant state updates in hot paths (check value changes before assignment)
- ForEach must use stable ID, forbid (for dynamic content)
.indices - Use /
LazyVStackfor large listsLazyHStack - Avoid inline filtering in ForEach, filter and cache in advance
- Keep View body pure, no side effects or complex logic
- Hand over complex performance profiling (hot path quantification, copy overhead modeling) to
swift-expert
动画
Animations
- 用 而非已废弃的
.animation(_:value:).animation(_:) - 按钮点击用
withAnimation - 动画修饰符放在被动画属性之后
- 过渡用 +
.transition()withAnimation
- Use instead of the deprecated
.animation(_:value:).animation(_:) - Use for button clicks
withAnimation - Place animation modifiers after the properties being animated
- Use +
.transition()for transitionswithAnimation
UIKit 核心规则
UIKit Core Rules
ViewController 结构
ViewController Structure
按顺序组织:Properties → UI Components → Lifecycle → Setup → Methods → Actions → Protocol Extensions
Organize in order: Properties → UI Components → Lifecycle → Setup → Methods → Actions → Protocol Extensions
布局
Layout
- 优先 SnapKit(如可用)或
NSLayoutConstraint.activate([]) - 优先 减少约束
UIStackView - 复杂列表用 +
UICollectionViewCompositionalLayoutDiffableDataSource
- Prioritize SnapKit (if available) or
NSLayoutConstraint.activate([]) - Prioritize to reduce constraints
UIStackView - Use +
UICollectionViewCompositionalLayoutfor complex listsDiffableDataSource
内存管理
Memory Management
- Delegate 必须
weak - 闭包捕获
[weak self] - Timer/观察者在 deinit 中清理
- Delegate must be
weak - Closures capture
[weak self] - Clean up Timer/observers in deinit
专项参考
Special References
深入学习特定主题时,查阅以下详细指南:
- SwiftUI 开发 - 状态管理、现代 API、列表性能、动画、布局最佳实践
- UIKit 开发 - ViewController 结构、布局、Cell 复用、自定义控件
- 导航架构 - Coordinator Pattern(UIKit)、NavigationStack + Router(SwiftUI)、深度链接
- 动画系统 - SwiftUI 动画(隐式/显式/过渡)、UIKit 动画、性能优化
- 性能优化 - SwiftUI 热路径优化、UIKit 视图层级优化、内存管理
- 组件设计 - 自定义组件、可配置 API、可复用模式
- 内存管理 - 循环引用、泄漏预防、weak/unowned 使用
When learning specific topics in depth, refer to the following detailed guides:
- SwiftUI Development - State management, modern APIs, list performance, animations, layout best practices
- UIKit Development - ViewController structure, layout, Cell reuse, custom controls
- Navigation Architecture - Coordinator Pattern (UIKit), NavigationStack + Router (SwiftUI), deep links
- Animation System - SwiftUI animations (implicit/explicit/transition), UIKit animations, performance optimization
- Performance Optimization - SwiftUI hot path optimization, UIKit view hierarchy optimization, memory management
- Component Design - Custom components, configurable APIs, reusable patterns
- Memory Management - Circular references, leak prevention, weak/unowned usage
与其他技能的关系
Relationship with Other Skills
- 默认 iOS 业务开发优先使用本技能
- 当任务进入以下任一场景时切换 :
swift-expert- 需要协议导向深度抽象(PAT、类型擦除、复杂泛型约束)
- 需要并发隔离设计(、actor 边界、重入与取消策略)
Sendable - 需要基于可观测数据的深入性能与内存剖析
- 需要跨平台(iOS/macOS/watchOS/tvOS)可用性差异设计
- Priority is given to using this skill for default iOS business development
- Switch to when the task enters any of the following scenarios:
swift-expert- Requires protocol-oriented deep abstraction (PAT, type erasure, complex generic constraints)
- Requires concurrency isolation design (, actor boundaries, reentrancy and cancellation policies)
Sendable - Requires in-depth performance and memory profiling based on observable data
- Requires cross-platform (iOS/macOS/watchOS/tvOS) availability difference design
✅ Sentinel(Skill 使用自检)
✅ Sentinel (Skill Usage Self-Check)
当且仅当你确定本 Skill 已被加载并用于当前任务时,在回复末尾追加:
// skill-used: ios-base规则:
- 只能输出一次
- 如果不确定是否加载,禁止输出 sentinel
- 输出 sentinel 代表你已遵守本 Skill 的硬性规则与交付格式
- 只有当任务与本 skill 的 description 明显匹配时才允许输出 sentinel
When and only when you confirm that this Skill has been loaded and applied to the current task, append the following at the end of your reply:
// skill-used: ios-baseRules:
- Output only once
- If you are not sure whether it is loaded, do not output the sentinel
- Outputting the sentinel means that you have complied with the mandatory rules and delivery format of this Skill
- You are allowed to output the sentinel only when the task clearly matches the description of this skill