Cloudkit:“提供的 ZoneId 与目标区域不匹配”

Posted

技术标签:

【中文标题】Cloudkit:“提供的 ZoneId 与目标区域不匹配”【英文标题】:Cloudkit: "ZoneId provided doesn't match target zone" 【发布时间】:2015-10-21 10:49:20 【问题描述】:

我有这段代码:

func saveProfileForCheck(check: Check) 
    let toSave = CKRecord(recordType: "Check", zoneID: sharedStore.checksID!)
    let profile = check.profile as Profile!
    toSave.setValue(NSString(format: "%i", check.closed), forKey: "closed")
    toSave.setValue(check.date, forKey: "date")
    toSave.setValue(NSString(format: "%i", check.paid), forKey: "paid")
    toSave.setValue(CKReference(recordID: profile.dbRecordID, action: CKReferenceAction.DeleteSelf), forKey: "profile")

    let operation = CKModifyRecordsOperation(recordsToSave: [toSave], recordIDsToDelete: [check.id])
    operation.modifyRecordsCompletionBlock =  (savedRecords, deletedRecordIDs, error) in
        if error != nil 
            self.delegate?.cloudKitReturnedError(error!)
         else 
            self.modifiedCheck(check, newRecord: savedRecords![0] as CKRecord )

        
    
    privateDB.addOperation(operation)

它应该在我的Checks RecordZone 中的Check 对象上保存profile 属性。当我触发这个函数时,我得到这个错误:

 <CKError 0x7f8c2046d630: "Partial Failure" (2/1011); "Failed to modify some records"; uuid = EF4CCE3F-3CDB-4506-BA43-464D7D9BD0F6; container ID = "mycontainer"; partial errors: 
130BD962-295C-4601-9343-2E4F4014C8C7:(Checks:__defaultOwner__) = <CKError 0x7f8c2045c680: "Invalid Arguments" (12/2006); server message = "ZoneId provided doesn't match target zone">
... 1 "Batch Request Failed" CKError's omited ...

>

我尝试了几件事:

检查 zoneID 是否真的正确,正确。 在方法中将 zoneID 硬编码为 CKRecordZoneID 对象。 在google和SO上查找错误,没有结果。

请注意,sharedstore.checksID 是一个实际 ID 而不是字符串,它是在应用启动时获取所有记录区域时创建的。

我该如何解决这个错误?任何建议将不胜感激。

【问题讨论】:

【参考方案1】:

您必须在操作上设置 zoneID,例如:

    operation.zoneID = CKRecordZoneID(zoneName: sharedStore.checksID!, ownerName: "your name")

更新:如下所述,.zoneID 仅适用于 CKQqueryOperation 而不是 CKModifyRecordsOperation

我相信只能将 CKReference 设置为同一区域中的记录。是这样吗?如果没有,那么您可以尝试在没有该引用的情况下保存记录吗?

来自文档:

将每个自定义区域视为一个独立的数据单元 数据库中的每个其他区域。在区域内,您将记录添加为 你会在其他任何地方。您还可以在记录之间创建链接 使用 CKReference 类在区域内。然而,CK 参考 类不支持跨区链接,所以每个引用对象 必须指向与当前记录在同一区域的记录

更新: 如果引用的源和目标位于默认区域中,则可以跨数据库(公共和私有)添加引用。

【讨论】:

我试过了。实际上是这样做的:CKRecordZoneID(zoneName: "Checks", ownerName: CKRecordZoneDefaultName)。不过我很欣赏你的评论,还有其他想法吗? 更新了问题,也许会澄清一点。您必须考虑到我的 sharedstore.checksID 是一个 NSString 或其他东西,但它实际上是一个合法的 CKRecordZoneID 对象。我知道它是合法的,因为我在所有云操作中都使用它,它在任何地方都像一个魅力,除了这个特殊的功能 好的,但是你仍然需要在操作上设置它,而不仅仅是在记录上。比如 operation.zoneID = sharedStore.checksID! 很有道理,我明天一有电脑就试试 @EdwinVermeer 如果您能提到可以跨数据库(公共和私有)添加引用,只要引用的源和目标位于默认区域中,这将对其他人有所帮助。这是链接公共和私人记录的唯一方法。

以上是关于Cloudkit:“提供的 ZoneId 与目标区域不匹配”的主要内容,如果未能解决你的问题,请参考以下文章

CloudKit 批量获取?

CloudKit 的单元测试

cloudKit:公共数据库中的 CKFetchRecordChangesOperation

无法初始化 CloudKit 架构,因为协调器中没有存储配置为使用 CloudKit

Cloudkit 与组合

Swift 2 和 Cloudkit 的通知