1️⃣ Codable 是什么?作用?使用方式
■ Codable 的本质
Codable 是 Swift 的数据序列化协议,用于将模型在内存对象 ↔ 可传输数据格式之间转换。
本质解决的是:
Model 的可传输性(Transportability)
而不仅仅是 JSON 解析。
■ Codable 的主要作用
1. 网络数据解析
struct Avatar: Codable {}用于:
JSON → Model
Model → JSON2. 本地持久化
例如:
FileManager 缓存
本地 JSON snapshot
SwiftData fallback
ABTest 配置缓存
聊天记录离线恢复
3. 并发安全复制
Codable 实际上也是一种稳定数据快照机制:
AsyncStream 传递
actor 间数据传递
background snapshot
diff comparison
4. 调试与日志
print(String(data: try JSONEncoder().encode(model), encoding: .utf8))调试极其方便。
■ Codable 的使用方式
自动合成
struct User: Codable {
var id: String
var name: String
}自定义 Key
struct User: Codable {
var userId: String
enum CodingKeys: String, CodingKey {
case userId = "user_id"
}
}自定义 decode / encode
用于:
数据容错
版本迁移
非标准 JSON
■ 关键认知
Codable 不是 JSON 协议
而是 Serialization 协议
JSON 只是其中一种 encoder。
2️⃣ Class 和 Struct 的核心区别
■ 根本差异
■ Struct 的优势(现代 SwiftUI 推荐)
1. 可预测状态
不会被其他地方悄悄修改。
2. SwiftUI diff 稳定
适合:
列表
streaming
timeline UI
snapshot animation
3. 并发安全
struct 更容易 Sendable。
4. 快照能力
适合缓存、Undo、乐观更新。
■ Class 的优势
1. 生命周期管理
适合:
Service
Manager
Router
Store
2. 共享状态
多个地方观察同一对象。
3. 对象身份(identity)
数据库与对象图场景非常重要。
■ 关键设计原则
struct 管数据
class 管生命周期
这是现代 Swift 架构最重要的经验之一。
3️⃣ SwiftUI 中必须使用 Class Model 的场景(双模型设计)
SwiftUI 推荐 struct,但某些框架必须使用 class,例如:
SwiftData (@Model)
CoreData
Firebase realtime object
ORM / 对象图系统
原因是:
需要对象身份
需要变更追踪
需要关系图
需要延迟加载
■ 解决方案:双模型架构(强烈推荐)
将模型拆为:
Persistence Entity(class)
Domain Model(struct)■ 示例
SwiftData Entity(class)
@Model
final class ChatMessageEntity {
var id: String
var content: String
}Domain Model(struct)
struct ChatMessage: Codable, Sendable, Hashable {
var id: String
var content: String
}Mapper
extension ChatMessageEntity {
func toDomain() -> ChatMessage {
ChatMessage(id: id, content: content)
}
}
extension ChatMessageEntity {
convenience init(domain: ChatMessage) {
self.init(id: domain.id, content: domain.content)
}
}■ 为什么双模型非常重要
1. UI 层保持值语义
避免 SwiftUI 更新异常。
2. 并发更安全
struct 更容易跨 actor 传递。
3. 可替换存储层
未来换数据库无需改 UI / Domain。
4. 缓存与 snapshot 更简单
非常适合 AIChats 的 streaming 架构。
■ Repository 建议
Interactor / Repository 输出 Domain struct,而不是 Entity。
UI 永远不要直接持有 SwiftData 对象作为状态。
■ 最终总结
Codable
解决模型的可传输与可持久化问题,是现代 Swift 数据层基础设施。
Struct vs Class
Struct 适合数据快照与并发,Class 适合生命周期与共享状态。
双模型架构
当框架必须使用 class(SwiftData 等)时,采用 Entity + Domain 拆分,是现代 SwiftUI 最推荐的方案。
如果你愿意,我可以帮你写下一篇:
👉 AIChats 完整数据流(Network → Cache → Domain → UI → Persistence)
👉 SwiftUI + VIPER 中 Model 的最佳分层
👉 如何避免 SwiftData 污染 Domain(非常关键)
这几篇连起来会是一套完整的架构笔记。