4.8 KiB
4.8 KiB
CLAUDE.md — iOS 客户端项目 AI 协作规范
项目概览
SwiftUI + MVVM 单向数据流 + SPM 多 target 模块化的 iOS「打卡/计划管理」客户端,功能对齐 wechat-clock-mini(小程序,生产参照)与 android-client(Android 端,原生简化参照)。架构对齐 Android NIA(core/* + feature/*)。
四个主入口 Tab(顺序):首页 / 打卡 / 计划 / 我的;另有独立登录页(手机号 + 短信验证码)与提交计划页(计划 Tab 内推入)。
目录结构
ios-client.xcodeproj/ios-client/:App 宿主(薄壳,只含@main挂载AppRootView)IosClientKit/:本地 SPM 包,承载所有模块Sources/App:组合根(AppContainerDI +AppRootView导航)Sources/CoreModel:领域模型(Sendable值类型,叶子)Sources/CoreCommon:通用工具(叶子)Sources/CoreDomain:Repository 协议 + UseCase(纯 Swift,不 import SwiftUI)Sources/CoreRepository:Repository 实现(Fake + 未来 OfflineFirst)Sources/CoreNetwork:DTO + APIClient(URLSession)Sources/CoreDatabase:SwiftData(@Model+ModelContainer)Sources/DesignSystem:设计 tokensSources/CoreUI:可复用 SwiftUI 组件Sources/FeatureHome:首页(落地页:Hero + 模块卡 + 产品介绍)Sources/FeatureCheckin:打卡(状态卡 + 状态 pill + 小组/个人记录)Sources/FeaturePlan:计划(周/月/年 + 小组统计 + 提交计划页)Sources/FeatureProfile:我的(资料 + 小组分组 + 退出登录)Sources/FeatureAuth:登录(手机号 + 短信验证码 + 60s 倒计时)
依赖方向(硬约束,违反即编译不过)
单向无环:App → feature → core;App 额外 → CoreRepository(装配具体实现)。
- 领域模型只在
CoreModel,其余模块只能 importCoreModel。 - Repository 协议只定义在
CoreDomain,实现在CoreRepository。 CoreDomain纯 Swift:禁止import SwiftUI/ 数据框架。- DTO 只在
CoreNetwork,领域 Model 只在CoreModel,二者分离。 - 禁止命名任何模块为
CoreData(与苹果CoreData框架撞名,已统一为CoreRepository)。
状态管理约定
- ViewModel:
@MainActor @Observable final class,持有uiState。 - UiState:
enum关联值(对应 Kotlinsealed interface)。 - Kotlin → Swift 映射:
| Android (Kotlin) | iOS (Swift) |
|---|---|
Flow<T> |
AsyncThrowingStream<T, Error> |
StateFlow + stateIn |
@Observable + @MainActor |
flatMapLatest |
Task 取消自动 switch-to-latest |
sealed interface UiState |
enum UiState(关联值) |
Hilt @Inject / AppContainer |
手写 AppContainer |
| Retrofit + kotlinx.serialization | URLSession + Codable |
| Room | SwiftData |
| DataStore(会话持久化) | Combine CurrentValueSubject(进程内 Fake 会话) |
会话 / 登录态
SessionRepository协议(CoreDomain)+FakeSessionRepository(CoreRepository,final class+ CombineCurrentValueSubject<Bool, Never>,默认未登录,AppContainer 持单例共享)。- 登录态驱动页面:
HomeViewModel双源切换(已登录observeHome()/ 游客observeGuestHome());checkin/plan/profile 四态含loggedOut。 - flatMapLatest 的 iOS 等价:外层
Task观察observeIsLoggedIn(),登录态变化时取消内层数据Task并重新订阅。 - 登录 mock 凭据:手机号
13812341234+ 验证码123456。
代码风格
- 跨模块符号一律
public,并加///文档注释。 - 领域模型标记
Sendable。 - 命名:类型 PascalCase,变量/函数 camelCase;UI 文案与注释可用中文。
明确禁止
- ❌ TCA、Swinject 等 DI 框架、Moya 等网络封装、任何第三方大框架
- ❌ UIKit(除非 SwiftUI 确无法覆盖的极少数场景)
- ❌ 循环依赖 / 反向 import
构建 / 验证命令
# 编译包(同时做依赖环检测,SPM 遇环即报错)
swift build --package-path IosClientKit
# 模拟器编译 App
xcodebuild -project ios-client.xcodeproj -scheme ios-client \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO build
# Lint
swiftlint lint --strict
新增 Feature 清单
- 在
IosClientKit/Package.swift的targets加FeatureXxx及依赖。 - 新建
Sources/FeatureXxx/:Screen + ViewModel + UiState(enum)。 - UseCase 放
CoreDomain,Repository 实现放CoreRepository。 - 在
App的AppContainer装配依赖、AppRootView接入导航。
文档地图
| 主题 | 文档 |
|---|---|
| 架构与数据流 | docs/architecture.md |
| 工作状态与遗留项 | docs/progress.md |
| 贡献指南 | CONTRIBUTING.md |