You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CoreData+CloudKit场景下检测iCloud存储配额超限?

检测iCloud存储配额超限的可行方案

问题背景

当iCloud存储已满时,CoreData + CloudKit同步会抛出Quota Exceeded(错误码25/2035),但常规同步回调可能无法直接捕获该错误,导致无法及时向用户展示提示。

解决方案

1. 监听CoreData CloudKit镜像代理通知

CoreData的CloudKit镜像代理会发送同步相关通知,可通过NotificationCenter监听NSCloudKitMirroringDelegateDidFinishExportingChangesNotification,从通知的userInfo中提取错误信息:

NotificationCenter.default.addObserver(forName: NSCloudKitMirroringDelegateDidFinishExportingChangesNotification, object: persistentContainer.cloudKitMirroringDelegate, queue: .main) { notification in
    guard let userInfo = notification.userInfo,
          let error = userInfo[NSCloudKitMirroringExportErrorKey] as? NSError else {
        return
    }
    
    // 解析CKError
    if let ckError = CKError(_nsError: error) {
        if ckError.code == .quotaExceeded {
            // 触发配额超限提示
            showQuotaExceededAlert()
        } else if ckError.code == .partialFailure, let partialErrors = ckError.partialErrorsByItemID {
            // 检查部分错误中是否包含配额超限
            for (_, partialError) in partialErrors {
                if let partialCKError = CKError(_nsError: partialError as NSError), partialCKError.code == .quotaExceeded {
                    showQuotaExceededAlert()
                    break
                }
            }
        }
    }
}

2. 主动查询CloudKit配额使用状态

使用CloudKit原生API直接查询当前配额使用情况,提前判断是否即将超限:

let container = CKContainer.default()
container.fetchQuotaUsageWithCompletionHandler { usedBytes, error in
    guard error == nil else {
        // 处理查询错误
        return
    }
    
    // 获取总配额并计算使用率
    container.accountStatus { status, accountError in
        if status == .available {
            container.fetchAccountInfo { accountInfo, infoError in
                guard let accountInfo = accountInfo else { return }
                let totalBytes = accountInfo.quotaBytes
                let usagePercentage = (Double(usedBytes) / Double(totalBytes)) * 100
                
                if usagePercentage > 90 { // 可自定义阈值,比如超过90%时提示
                    DispatchQueue.main.async {
                        showQuotaWarningAlert()
                    }
                }
            }
        }
    }
}

3. 捕获CoreData保存时的深层错误

在CoreData保存操作的回调中,递归解析错误链,查找是否包含CKError.quotaExceeded:

context.save { success, error in
    if let error = error {
        var currentError: Error = error
        // 遍历错误链,获取底层CKError
        while let underlyingError = currentError._userInfo[NSUnderlyingErrorKey] as? Error {
            currentError = underlyingError
            if let ckError = currentError as? CKError, ckError.code == .quotaExceeded {
                showQuotaExceededAlert()
                break
            }
        }
    }
}

注意事项

  • 需在NSPersistentCloudKitContainer初始化完成后再设置通知监听。
  • 部分错误会被CoreData多层包装,需通过NSUnderlyingErrorKey递归解析原始CKError。
  • 主动查询配额的方法依赖用户已登录iCloud账号,需先检查CKAccountStatus。

内容的提问来源于stack exchange,提问作者Russ Neufeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 06:45:27