【问题标题】:Reconcile deleted CKRecord to CoreData NSManagedObject将已删除的 CKRecord 与 CoreData NSManagedObject 协调一致
【发布时间】:2019-11-04 09:37:25
【问题描述】:

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

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

我不知道我是否会以错误的方式处理这一切,是否有更简单的方法来处理所有这些!

【问题讨论】:

    标签: core-data cloudkit nsmanagedobject ckrecord ckquerysubscription


    【解决方案1】:

    这行得通,但感觉有点笨拙。一定有更简单的方法!但如果不是,如果此代码对其他人有用,如果您希望在任何未显示的辅助方法中使用的代码(例如在 +[CoreDataFunctions fetchRecordsForEntityType: withCloudIDs: completion:] 方法中),请随时发表评论;

    //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];
        });
    }];
    

    【讨论】:

      【解决方案2】:

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

      如果调用“application(didReceiveRemoteNotification:)”方法,如果构建并触发“CKFetchRecordZoneChangesOperation”。

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

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

      【讨论】:

        猜你喜欢
        • 2020-02-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-01-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-04-11
        相关资源
        最近更新 更多