使用NSPersistentCloudKitContainer时如何处理CKError及quotaExceeded错误
NSPersistentCloudKitContainer quotaExceeded 错误捕获与处理方案
你要的步骤2核心是监听NSPersistentCloudKitContainer的同步事件通知,从事件参数中提取底层CKError,具体实现如下:
实现步骤
- 首先在初始化持久化容器完成后,注册
NSPersistentCloudKitContainer.eventChangedNotification系统通知,该通知会在容器每次执行CloudKit同步操作(上传/下载/合并数据)时触发,包含同步的状态、类型和错误信息。 - 实现通知回调方法,从通知的userInfo中取出同步事件对象,判断事件是否执行失败,再取出底层错误转换为CKError,校验错误码是否为
CKError.Code.quotaExceeded。 - 捕获到目标错误后,切主线程执行用户提示逻辑。
示例代码
// 持久化容器初始化完成后注册通知 NotificationCenter.default.addObserver( self, selector: #selector(handleCloudKitSyncEvent(_:)), name: NSPersistentCloudKitContainer.eventChangedNotification, object: persistentContainer ) // 通知回调处理 @objc private func handleCloudKitSyncEvent(_ notification: Notification) { // 取出同步事件对象 guard let event = notification.userInfo?[NSPersistentCloudKitContainer.eventUserInfoKey] as? NSPersistentCloudKitContainer.Event else { return } // 仅处理失败的同步事件 guard !event.succeeded, let ckError = event.error as? CKError else { return } // 匹配iCloud存储空间已满错误 if ckError.code == .quotaExceeded { DispatchQueue.main.async { // 这里调用你的自定义弹窗/通知方法,完成步骤3 self.showICloudStorageFullAlert() } return } // 通用CKError处理扩展,可根据业务需要添加 switch ckError.code { case .notAuthenticated: // 处理用户未登录iCloud场景 case .networkUnavailable, .networkFailure: // 处理网络异常场景 case .operationCancelled: // 处理同步取消场景 default: break } }
注意事项
- 同步事件回调默认在后台线程触发,所有UI操作必须切换到主线程执行,避免崩溃。
- 上述事件通知方案仅支持iOS14及以上系统,如果你的App需要兼容iOS13,可监听
NSPersistentStoreRemoteChangeNotification,同时在加载持久化存储时设置NSPersistentStoreDescription的shouldAddStoreAsynchronously为true,在加载完成的回调中处理错误,iOS13下CloudKit同步错误的捕获粒度较粗,优先建议适配iOS14及以上系统。 - 建议增加防抖逻辑,例如24小时内最多提示1次iCloud空间不足,避免频繁弹窗打扰用户。
- 提示用户时可明确说明:本地数据读写不受影响,仅跨设备同步暂时失效,用户清理iCloud空间后同步会自动恢复,无需额外操作。
内容的提问来源于stack exchange,提问作者Crew3339
相关产品推荐
相关产品推荐

