CloudKit 和 iCloud Documents 怎么选:先看数据是设置、文件还是对象
type
status
date
slug
summary
tags
category
icon
password
wechat_gate

CloudKit 和 iCloud Documents 怎么选?别先看它们是不是都属于 iCloud,先看数据是少量设置、用户文件,还是需要查询和关系的结构化对象。对应的答案分别是 Key-Value Storage、iCloud Documents 和 CloudKit。
这个区分看似简单,但 Xcode 把三个复选框放在同一张 Capability 卡片里,很容易让人误以为 CloudKit 是 iCloud Documents 的“增强模式”。它不是。CloudKit 是一套独立的云数据库服务,不会因为多勾一个选项就让文件同步更快。
先给结论:按数据语义选,不按“是否上云”选
服务 | 核心数据形态 | 适合场景 | 常用入口 |
Key-Value Storage | 少量键值 | 主题、字号、功能开关、最近选择 | NSUbiquitousKeyValueStore |
iCloud Documents | 文件和目录 | Markdown、图片、PDF、工程文件 | FileManager、NSDocument、NSMetadataQuery |
CloudKit | Record、字段和关系 | 结构化查询、共享、协作、公共数据 | NSPersistentCloudKitContainer、CKSyncEngine、CKDatabase |
Apple 的当前选型文档也是这个思路:如果 App 创建文档和图片,并希望它们在同一用户的设备间同步,使用 iCloud Documents;如果管理的是含关系的复杂模型对象,再进入 CloudKit 的选型。

我在 MarkZen 上遇到的具体选择
我在给 MarkZen 的 iOS target 配置 iCloud 时,真正卡住的不是 API,而是一个复选框:既然已经启用 iCloud Documents,CloudKit 要不要也顺手勾上?
MarkZen 的核心数据结构很直接:
Markdown 原文件、目录层级、附件目录和相对引用都是业务语义,不是可以随意打散的存储细节。因此最后的配置是:
- Key-value storage:启用,同步少量跨设备状态。
- iCloud Documents:启用,保存笔记与附件文件。
- CloudKit:不启用,因为当前没有 Record、关系查询或跨用户协作需求。
这次最有价值的教训是:Capability 是权限入口,不是免费的性能开关。 如果在数据模型确定前先勾 CloudKit,后面就会被迫回答 Schema、冲突、重试、生产环境部署等一数据库问题。对文件型 App 来说,这些成本没有换来新能力。
CloudKit 和 iCloud Documents 怎么选:只问三个问题
问题一:它是不是少量、低频的设置?
如果数据是编辑器字号、主题、功能开关或最近选择,先看 Key-Value Storage。Apple 的当前示例明确把它定位为跨设备同步偏好、配置和简单 App 状态的工具,总容量上限为 1 MB,不应该替代大量本地数据存储。
一个常见错误是把整个模型序列化后塞进一个 key。这会把局部变更放大成整块数据更新,也会让版本兼容迅速变得难以控制。
问题二:文件名、目录和原始格式是不是产品的一部分?
如果答案是“是”,优先 iCloud Documents。App 把文件放进 ubiquity container,系统参与持久化和设备间同步,文件仍然保留文件语义。
对 Markdown 编辑器、图片管理器和文档型工具来说,“它还是一个可理解的文件”往往比“它被拆成了可查询字段”更重要。
问题三:是否需要按字段查询、维护关系或管理共享?
这才是 CloudKit 的主场。典型需求包括:
- 查询最近七天修改的笔记,再按标签或作者筛选。
- 管理用户、项目、任务、评论和附件之间的关系。
- 让不同 iCloud 用户共享记录,并由 App 管理参与者与权限。
- 建立公共模板库或其他所有用户可读的结构化内容。
CloudKit 可以通过
CKAsset 携带图片或其他二进制数据,但 Asset 仍然是 Record 的字段,不是 iCloud Drive 中的文件树。文件名、路径、版本和删除规则都要由 App 的模型另外承担。
勾选 CloudKit,实际改变了什么
在 Xcode 中勾选 CloudKit 后,项目的签名和 Entitlement 会声明 App 可以访问相应的 CloudKit container。例如,文件服务的声明包含
CloudDocuments:同时使用 CloudKit 时,数组中会增加
CloudKit:但这些只是授权声明。勾选不会自动完成以下任务:
- 把现有文件转换成
CKRecord。
- 设计数据库 Schema 和索引。
- 处理冲突、部分失败、限流和重试。
- 完成开发 Schema 到生产环境的部署。
- 解决未登录 iCloud、离线和账户切换的行为。
发布前,不要只看 Xcode 界面是否有勾选。可以对构建产物检查最终签入的权限:
需要 CloudKit 之后,还要选接入层级
接入方式 | 适合情况 | 主要成本 |
NSPersistentCloudKitContainer | 已使用 Core Data,不需要精细控制每次同步 | 需要理解 Core Data 与 CloudKit 的兼容边界 |
CKSyncEngine | 保留自有本地模型,由系统协助调度变更上传和拉取 | App 仍要处理同步事件并提供变更记录 |
CKDatabase 与 CKOperation | 需要完整控制数据模型和同步过程 | 手动处理冲突、token、通知、重试和账户变化 |
“要用 CloudKit”不等于“要从最底层的 API 开始”。越高的控制力通常意味着越多同步责任,应该根据现有本地模型和业务需求选择。
混合使用往往比二选一更合理
一个 App 可以让不同数据进入不同的存储系统:
对 MarkZen 来说,未来如果增加公共模板库、跨用户协作、评论或成员权限,可以把这些结构化元数据放进 CloudKit。原有 Markdown 和附件仍然可以留在 iCloud Documents,不需要为了一个新功能破坏已经成立的文件工作流。
发布前用这份清单再判断一次
- 数据是设置、文件,还是结构化对象?
- 是否需要远程按字段查询、对象关系或参与者权限?
- 如果不勾 CloudKit,当前哪个已确定的功能无法实现?
- 团队是否准备好管理 Schema、冲突、重试、账户变化和生产环境部署?
- 构建产物中的 Entitlement 是否与真实依赖一致?
如果第 3 个问题没有具体答案,就不要为“以后可能会用”提前开启 CloudKit。
结论
CloudKit 值得用,但它解决的是数据库问题,不是“更强的 iCloud 同步”。少量设置用 Key-Value Storage,用户文件用 iCloud Documents,需要查询、关系、共享或公共数据时再使用 CloudKit。
对文件型 App 来说,不勾选 CloudKit 不是能力缺失,而是没有让一套不需要的数据库生命周期混入已经清晰的文件架构。
参考资料
相关阅读
2026.08.14 17:27
沪 · 赵巷