Jon*_*han 8 objective-c ios icloud cloudkit
我正在尝试使用CloudKit上传一些记录更改.我正在使用CKModifyRecordsOperation来批量上传设备上已更改的记录.记录都在自定义区域中
由于某种原因,操作不断回来,并告诉我""保护数据不匹配"
这是代码:
- (void)updloadLocalChangesWithCompletionBlock:(void (^)(NSError *error))completionBlock
{
// Initialize the data
NSArray *localChanges = self.localChanges;
NSArray *localDeletions = self.localDeletions;
// Initialize the database and modify records operation
CKDatabase *database = [CKContainer defaultContainer].privateCloudDatabase;
CKModifyRecordsOperation *modifyRecordsOperation = [[CKModifyRecordsOperation alloc] initWithRecordsToSave:localChanges recordIDsToDelete:localDeletions];
modifyRecordsOperation.savePolicy = CKRecordSaveAllKeys;
NSLog(@"CLOUDKIT Changes Uploading: %d", localChanges.count);
// Add the completion block
modifyRecordsOperation.modifyRecordsCompletionBlock = ^(NSArray *savedRecords, NSArray *deletedRecordIDs, NSError *error) {
if (error) {
NSLog(@"[%@] Error pushing local data: %@", self.class, error);
}
[self.localChanges removeObjectsInArray:savedRecords];
[self.localDeletions removeObjectsInArray:deletedRecordIDs];
completionBlock(error);
};
// Start the operation
[database addOperation:modifyRecordsOperation];
}
Run Code Online (Sandbox Code Playgroud)
这是它给我的错误:
[CloudKitSyncManager] Error Uploading Changes: <CKError 0x156654a0: "Partial Failure" (2/1011); "Failed to modify some records"; partial errors: {
default-00001:(ZoneName:UserRecordID) = <CKError 0x1550b5a0: "Server Record Changed" (14/2037); "Error saving record <CKRecordID: 0x18080430; default-00001:(ZoneName:UserRecordID)> to server: Protection data didn't match">
}>
Run Code Online (Sandbox Code Playgroud)
如果使用savePolicyof CKRecordSaveIfServerRecordUnchanged,则需要预先获取远程CKRecord(并更新该特定实例)CKModifyRecordsOperation.如果您CKRecord通过CKRecordID匹配分配"本地" 并向上引用它initWithRecordName:,则CloudKit无法将远程更改标记与(缺少的)本地更改标记进行比较,因此它会失败,CKErrorServerRecordChanged并且会出现一些模糊的错误消息:"保护数据没有不匹配.
但是,如果CKRecord根本不存在远程,则服务器记录肯定没有更改,并且保存操作可以继续.此行为是"Save If Not Exists"用例的基础(SQL:INSERT over PRIMARY KEY).如果您分配一个"本地" CKRecord和使用savePolicy的CKRecordSaveIfServerRecordUnchanged,它会插入,但从来没有进行更新.
如果你使用savePolicyof CKRecordSaveAllKeys和CKRecordZoneID ownerNameof CKOwnerDefaultName,你应该能够通过"本地"分配保存(SQL:UPDATE,必要时使用INSERT),通过CKRecord网络保存(预取)行程.
如果没有网络上的(验证)行程,可能无法完成"Save If Exists"用例(SQL:UPDATE over PRIMARY KEY).
一个问题:无法将CKRecordSaveIfServerRecordUnchangedINSERT和CKRecordSaveAllKeysUPDATE同时转换为一个原子事务,因为CloudKit事务CKModifyRecordsOperation跨越多个CKRecord/ CKRecordID实例只跨越一个事务.从哲学上讲,"事务"应该能够跨越多个"操作"(SQL:查询),而不仅仅是多个"记录"(SQL:行).
你的self.localChanges阵列究竟是什么?CKRecord我假设,但您是根据从CloudKit下载的相同CKRecord对象上传的修改记录吗?
当我尝试使用我的本地更改上传新分配的CKRecord并期望它覆盖服务器的副本时,我有一个类似的(虽然不是确切的)错误消息.我通过下载我的项目的远程副本,将更新应用于CloudKit提供给我的CKRecord实例,然后上传它来修复它.