Administrator
发布于 2026-02-25 / 4 阅读
0
0

Swift 数据模型设计核心总结


1️⃣ Codable 是什么?作用?使用方式

■ Codable 的本质

Codable 是 Swift 的数据序列化协议,用于将模型在内存对象 ↔ 可传输数据格式之间转换。

本质解决的是:

Model 的可传输性(Transportability)

而不仅仅是 JSON 解析。


■ Codable 的主要作用

1. 网络数据解析

struct Avatar: Codable {}

用于:

JSON → Model
Model → JSON


2. 本地持久化

例如:

  • 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

Class

语义

值语义

引用语义

共享状态

不共享

共享

并发安全

更安全

需要额外控制

Sendable

天然更友好

默认不安全

SwiftUI diff

稳定

容易幽灵更新

生命周期

无生命周期

有生命周期


■ 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(非常关键)

这几篇连起来会是一套完整的架构笔记。


评论