使用 CKContainer 查询 CloudKit 同步状态
了解如何通过 CloudKit 的 accountStatus() 方法,查询用户 iCloud 账户的同步状态。

理解 CKAccountStatus:表示 iCloud 可用状态
CKAccountStatus
是 CloudKit 框架中,用于表示用户 iCloud 账户可用性的枚举,提供了 5 种状态:

开发文档的解释如下:

理解 CKContainer 类(基础)
CKContainer
是 CloudKit 框架中的核心类,它代表了一个 iCloud 容器。每个容器可以理解为云端数据存储的一个隔离环境。
和 CKContainer 同级的其他类
CloudKit 框架包含多个类,分别用于不同的职责:
- CKQuery - CloudKit 查询,用于检索云端数据
- CKQueryOperation - CloudKit 查询操作
- CKRecord - CloudKit 记录,代表云中存储的一个数据项
查询 CloudKit 同步状态主要使用 CKContainer 中的方法,因此,这篇文章主要讲解 CKContainer 类。
CKContainer 负责的功能
身份验证与访问控制:
- 确定用户是否登录了 iCloud 账户
- 管理应用对 iCloud 数据的访问权限
- 提供用户身份信息(在保护隐私的前提下)
数据库访问:
- 提供对三种数据库的访问:
publicCloudDatabase
(公共数据库,所有用户可读)privateCloudDatabase
(私有数据库,仅用户本人可访问)sharedCloudDatabase
(共享数据库,用于协作)
容器配置:
- 管理云端存储配额
- 提供容器元数据和配置信息
CKContainer.default()
每个启用了 iCloud 能力的应用都至少有一个容器。
当你的代码调用 CKContainer.default()
时,获取的是应用的默认容器。
通过这个容器对象,可以执行所有 CloudKit 相关操作,包括身份验证、数据存储、查询等。
CKContainer.default().accountStatus()
accountStatus
方法用于确定当前设备上的 iCloud 账户状态,返回的 CKAccountStatus
枚举。
这个方法是开发 iCloud 功能的第一步,因为在确认用户有可用的 iCloud 账户前,其他 CloudKit 操作都无法进行。
使用 accountStatus() 方法查询同步状态
accountStatus()
是 CloudKit 框架中的 CKContainer 类中的一个方法。它会返回一个 CKAccountStatus
对象。

Apple 为 accountStatus()
方法提供了新的 Swift Concurrency 版本:

我们可以创建一个 fetchCloudKitAccountStatus()
方法,用于获取同步状态,并添加 logger 输出:

在 View 中显示状态
使用 MVVM 架构,
- 创建一个 CloudSyncViewModel 文件,用于获取 iCloud 同步状态
- 创建一个 CloudSyncSettingsView 文件,用于展示 iCloud 同步状态
由于 CloudKit 框架中的 CKAccountStatus 枚举并没有内置本地化的 description 描述,因此,我们还需要创建一个 iCloudStatus 枚举,便于显示本地化文本信息:
import SwiftUI
/// iCloud 状态枚举
enum iCloudStatus {
case checking
case enabled // 我们自定义的"已启用"状态
case available // 对应CKAccountStatus.available - 用户的iCloud账户可用
case noAccount // 对应CKAccountStatus.noAccount - 设备没有登录iCloud账户
case restricted // 对应CKAccountStatus.restricted - 系统拒绝访问用户的iCloud账户
case temporarilyUnavailable // 对应CKAccountStatus.temporarilyUnavailable - 用户的iCloud账户暂时不可用
case couldNotDetermine // 对应CKAccountStatus.couldNotDetermine - CloudKit无法确定用户的iCloud账户状态
var description: String {
switch self {
case .checking:
return "检查中..."
case .enabled:
return "已启用"
case .available:
return "账户可用"
case .noAccount:
return "未登录iCloud"
case .restricted:
return "访问受限"
case .temporarilyUnavailable:
return "暂时不可用"
case .couldNotDetermine:
return "状态未知"
}
}
var message: String {
switch self {
case .checking:
return "正在检查 iCloud 同步状态..."
case .enabled:
return "数据正在通过 iCloud 同步至所有使用相同 Apple ID 的设备。"
case .available:
return
"您的 iCloud 账户可用。启用 iCloud 同步后,您的用户数据将在所有使用相同 Apple ID 的设备上保持同步。"
case .noAccount:
return "设备未登录 iCloud 账户。请在系统设置中登录 iCloud 账户以启用同步功能。"
case .restricted:
return "系统拒绝访问您的 iCloud 账户。请检查您的隐私设置。"
case .temporarilyUnavailable:
return "您的 iCloud 账户暂时不可用,请稍后再试。"
case .couldNotDetermine:
return "CloudKit 无法确定您的 iCloud 账户状态,请检查网络连接后再试。"
}
}
var color: Color {
switch self {
case .checking:
return .gray
case .enabled:
return .green
case .available:
return .blue
case .noAccount, .restricted, .temporarilyUnavailable,
.couldNotDetermine:
return .orange
}
}
}
