CloudKit 是什么

CloudKit 是苹果的云数据库服务,直接把 iCloud 能力交给 App:存储结构化记录、文件、键值数据,还能跨设备实时同步。它免后端搭建,适合个人数据类应用。

用户的数据跟着 iCloud 走,App 只管读写。

三种存储:私有库(用户私有,容量随 iCloud 套餐)、共享库(多人协作)、公共库(所有用户共享,有配额)。记笔记、记账、待办这类 App,私有库是主场。

容器与数据库

先在开发者后台建 Container,代码里用 CKContainer 拿到数据库。默认的 defaultContainer 对应主容器,多容器场景逐个初始化。

let container = CKContainer.default()
let privateDB = container.privateCloudDatabase
// 记录类型在 CloudKit Console 里定义好字段
CloudKit 基本概念
  • CKRecord一条记录。
  • CKRecordZone记录分区。
  • CKQuery查询。
  • CKSubscription变更订阅。

记录类型(如 Note、Task)在 Console 定义,字段类型有 String、Int、Asset 等。Schema 变更要小心,线上改类型可能报错,开发期尽早定型。

记录与查询

保存记录用 save,查询用 CKQuery 加谓词。CloudKit 的查询是异步的,配合 async/await 写起来很顺。

let record = CKRecord(recordType: "Note")
record["title"] = "标题"
record["content"] = "内容"
try await privateDB.save(record)

let predicate = NSPredicate(format: "title CONTAINS %@", "云")
let query = CKQuery(recordType: "Note", predicate: predicate)
let result = try await privateDB.records(matching: query)
CloudKit:发光云朵居上、下方平板手机笔记本三台设备与同步箭头相连、其间数据点的蓝调插画
云端与多设备互联。

查询结果分页用 CKQueryOperation 的 cursor 继续拉。复杂筛选尽量在谓词里做,客户端过滤数据多时性能差。

写查询前先想清楚索引:CloudKit 的查询性能依赖字段索引,Console 里给常用筛选字段建索引,查询才会快。复杂查询拆成几次简单查询,别指望一条大查询包打天下。记录大小也有限制,大文件(图片、音频)用 CKAsset 存,字符串和二进制数据别硬塞进记录字段。批量操作时一次处理一批,配合 modifyRecords 批量保存或删除,网络往返少一大半。

数据安全要守住两条线:私有库的数据权限由 iCloud 账号天然隔离,但应用内仍要做账号维度校验;公共库写入要谨慎,别把用户隐私写进公共区域。

订阅与推送

订阅让云端在记录变化时推送通知:别的设备改了数据,这台设备能立刻知道。订阅分查询订阅和记录区域订阅。

let sub = CKQuerySubscription(
  recordType: "Note",
  predicate: NSPredicate(value: true),
  subscriptionID: "note-changes",
  options: [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
)
sub.notificationInfo = CKNotificationInfo()
sub.notificationInfo?.alertBody = "数据已更新"
try await privateDB.save(sub)

收到远程通知后,解析 CKQueryNotification 里的 recordID,再去拉最新数据更新本地。订阅 ID 全局唯一,重复创建会报错,先查再建。

推送到达率不是百分之百,应用启动时还要主动拉一次最新数据兜底,别只依赖推送通知;同时做好幂等处理,同一批更新无论收到几次,本地结果一致。通知负载里只放记录 ID 和变更类型,正文数据走按需拉取,避免推送体积撑爆限制。