Core data 将删除的CKRecord与CoreData NSManagedObject进行核对

Core data 将删除的CKRecord与CoreData NSManagedObject进行核对,core-data,cloudkit,nsmanagedobject,ckrecord,ckquerysubscription,Core Data,Cloudkit,Nsmanagedobject,Ckrecord,Ckquerysubscription,我已经创建了CKQuerySubscriptions来监控CKRecords的远程插入、修改和删除。对于插入和修改的记录,这很有效,因为我可以查询受影响的CKRecord的CloudKit,获取相关的NSManagedObject,然后从那里处理插入和修改 对于已删除的CKRecords,这是一个问题,因为在触发通知时,CKRecord已从CloudKit中删除。这意味着获取现在已删除的CKRecord的获取请求失败,因此我无法知道哪个NSManagedObject与已删除的CKRecord关联

我已经创建了
CKQuerySubscription
s来监控
CKRecord
s的远程插入、修改和删除。对于插入和修改的记录,这很有效,因为我可以查询受影响的
CKRecord
CloudKit
,获取相关的
NSManagedObject
,然后从那里处理插入和修改

对于已删除的
CKRecord
s,这是一个问题,因为在触发通知时,
CKRecord
已从
CloudKit
中删除。这意味着获取现在已删除的
CKRecord
的获取请求失败,因此我无法知道哪个
NSManagedObject
与已删除的
CKRecord
关联


我不知道我是否走错了路,是否有更简单的方法来处理这一切

这很管用,但感觉有点笨重。一定有更简单的办法!但如果没有,如果此代码对其他任何人都有用,如果您希望在任何帮助器方法中使用的代码未显示(例如在
+[CoreDataFunctions fetchRecordsForEntityType:withcloudid:completion:
方法中),请随时发表评论

//用于保存现有NSManagedObject实例的所有CloudID的数组
NSMutableArray*cloudIDs=[NSMutableArray];
//使用现有NSManagedObject实例的ID填充cloudIDs数组
for(self.items中的NSManagedObject*项){
nsuid*cloudID=[项目值forkey:@“cloudID”];
[cloudIDs addObject:cloudID];
}
//用于保存剩余NSManagedObject实例(即未删除的实例)的数组
NSMutableArray*remainingItems=[NSMutableArray];
//获取所有剩余的CKRecords(即未删除的记录
[CoreDataFunctions fetchRecordsForEntityType:[self-managedObjectMonitoringClass]with CloudId:CloudId完成:^(NSArray*结果){
//对于每个本地NSManagedObject实例
for(self.items中的NSManagedObject*项){
//本地NSManagedObject实例的cloudID
NSString*localCloudID=[[item valueForKey:@“cloudID”]uuistring];
//对于CloudKit中的每个记录
用于(CKRecord*结果中的记录){
//远程CKRecord对象的cloudID
NSString*remoteCloudID=[记录值forkey:@“CD_cloudID”];
//如果本地和远程CloudID匹配,则本地NSManagedObject实体表示仍然存在于CloudKit中的CKRecord
//将NSManagedObject实体添加到remainingItems数组中
if([remoteCloudID IsequalString:localCloudID]){
[剩余项添加对象:项];
打破
}
}
}
//用于保存要从collectionView中删除的NSIndexPath对象的数组
NSMutableArray*索引路径=[NSMutableArray];
//对于本地存储的每个NSManagedObject
for(self.items中的NSManagedObject*项){
//如果remainingItems数组不包含此NSManagedObject,则它已从CloudKit中删除
//为此项创建和索引XPath,并将其添加到数组中
如果(![RemaingItems containsObject:item]){
NSInteger索引=[self.items索引对象:item];
[indexPaths addObject:[NSIndexPath indexPathForItem:索引项:0]];
}
}
dispatch\u async(dispatch\u get\u main\u queue()^{
[[self-TBcollectionView]性能更新:^{
//将本地项数组设置为CloudKit中剩余的内容
self.items=剩余项;
//删除已删除项目的索引路径
[[self-TBcollectionView]deleteemsatindexpaths:indexPaths];
}完成:无];
});
}];

我使用带有远程通知和CKFetchRecordZoneChangesOperation的订阅

如果调用了“application(didReceiveEmotentification:)”方法,如果生成并触发“CKFetchRecordZoneChangesOperation”

有几个完成处理程序。一个用于更新的记录(添加/修改),另一个用于删除的记录

此处理程序称为“recordWithIDWasDeletedBlock”,为已删除的每条记录调用,提供已删除记录的recordID。有了此信息,您应该能够处理所需的内容

//Array to hold all cloudIDs of existing NSManagedObject instances
NSMutableArray *cloudIDs = [NSMutableArray array];

//Populate cloudIDs array with the IDs of the existing NSManagedObject instances
for (NSManagedObject *item in self.items) {
    NSUUID *cloudID = [item valueForKey:@"cloudID"];
    [cloudIDs addObject:cloudID];
}

//Array to hold remaining NSManagedObject instances (i.e. the ones which were not deleted)
NSMutableArray *remainingItems = [NSMutableArray array];

//Fetch all remaining CKRecords (i.e. the ones which were not deleted
[CoreDataFunctions fetchRecordsForEntityType:[self managedObjectMonitoringClass] withCloudIDs:cloudIDs completion:^(NSArray<CKRecord *> *results) {
    //For each local NSManagedObject instance
    for (NSManagedObject *item in self.items) {
        //The cloudID for the local NSManagedObject instance
        NSString *localCloudID = [[item valueForKey:@"cloudID"] UUIDString];

        //For each CKRecord in CloudKit
        for (CKRecord *record in results) {
            //The cloudID for the remote CKRecord object
            NSString *remoteCloudID = [record valueForKey:@"CD_cloudID"];

            //If the local and remote cloudIDs match, the local NSManagedObject entity represents a CKRecord which still exists in CloudKit
            //Add the NSManagedObject entity to the remainingItems array
            if ([remoteCloudID isEqualToString:localCloudID]) {
                [remainingItems addObject:item];
                break;
            }
        }
    }

    //Array to hold NSIndexPath objects to be removed from the collectionView
    NSMutableArray *indexPaths = [NSMutableArray array];

    //For each NSManagedObject stored locally
    for (NSManagedObject *item in self.items) {
        //If the remainingItems array does not contain this NSManagedObject, it has been deleted from CloudKit
        //Create and indexPath for this item and add it to the array
        if (![remainingItems containsObject:item]) {
            NSInteger index = [self.items indexOfObject:item];
            [indexPaths addObject:[NSIndexPath indexPathForItem:index inSection:0]];
        }
    }

    dispatch_async(dispatch_get_main_queue(), ^{
        [[self TBcollectionView] performBatchUpdates:^{
            //Set the local items array to whatever is remaining in CloudKit
            self.items = remainingItems;
            //Delete the indexPaths for the items which were deleted
            [[self TBcollectionView] deleteItemsAtIndexPaths:indexPaths];
        } completion:nil];
    });
}];