首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检索更改的CloudKit记录时识别记录更改类型

检索更改的CloudKit记录时识别记录更改类型
EN

Stack Overflow用户
提问于 2019-06-04 01:22:37
回答 2查看 413关注 0票数 0

我正在尝试使用CloudKit同步和本地CoreData完成一个应用程序。大多数操作都像预期的那样工作,但我找不到确定CloudKit报告的更改类型的方法。我得到了更改的记录,但我需要知道更改是编辑、新记录还是删除。如有任何指导,将不胜感激。

下面是我认为可以配置的代码,以识别我需要对CoreData进行的编辑类型。Xcode 10.2.1 iOS 12.2 Swift (最新)

代码语言:javascript
复制
func fetchZoneChangesInZones( _ zones : [CKRecordZone.ID], _ completionHandler: @escaping (Error?) -> Void) {

    var fetchConfigurations = [CKRecordZone.ID : CKFetchRecordZoneChangesOperation.ZoneConfiguration]()

    for zone in zones {
        if let changeToken = UserDefaults.standard.zoneChangeToken(forZone: zone) {
            let configuration = CKFetchRecordZoneChangesOperation.ZoneConfiguration(previousServerChangeToken: changeToken, resultsLimit: nil, desiredKeys: nil)
            fetchConfigurations[zone] = configuration
        }//if let changeToken

    }//for in

    let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: zones, configurationsByRecordZoneID: fetchConfigurations)

    operation.fetchAllChanges = true

    var changedPatients = [CKRecord]()
    var changedCategory1s = [CKRecord]()

    //I thought that I should be able to query for the change type here and make separate arrays for each change type
    operation.recordChangedBlock = { record in
        if record.recordType == "Patient" {
            changedPatients.append(record)
        }
    }//recordChangedBlock

    operation.fetchRecordZoneChangesCompletionBlock = { [weak self] error in
        for record in changedPatients {
            //my actions here - need to choose new, changed or delete
            self!.saveCKRecordToCoreData(record: record)
        }//for record in

        completionHandler(error)

    }//fetchRecordZoneChangesCompletionBlock

    operation.recordZoneFetchCompletionBlock = { recordZone, changeToken, data, moreComing, error in
        UserDefaults.standard.set(changeToken, forZone: recordZone)
    }//recordZoneFetchCompletionBlock

    privateDatabase.add(operation)

}//fetchZoneChangesInZones
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-05 21:11:47

解决方案是正在使用的操作版本上的单独方法。我已经收到通知了,只是不知道它们是更新、创建还是删除。可以通过搜索recordName( UUID)的核心数据来处理更新和创建。如果找到,然后编辑,如果没有创建。问题是删除-使用fetchRecordZoneChangesCompletionBlock无法识别删除。然而,操作族有一个仅用于报告删除( operation.recordWithIDWasDeletedBlock )的方法。我修改了以前的代码,并添加了如下所示的删除代码。

我的单个数据库订阅涵盖了整个私有数据库,因此不需要订阅每种记录类型。

代码语言:javascript
复制
operation.fetchRecordZoneChangesCompletionBlock = { error in
        for record in changedPatients {

            //search for the record in coredata
            if self.isSingleCoreDataRecord(ckRecord: record) {
                //if found - then modify
                self.saveUpdatedCloudKitRecordToCoreData(record: record)
            } else {
                //else add new
                self.saveCKRecordToCoreData(record: record)
            }

        }//for record in

        completionHandler(error)

}//fetchRecordZoneChangesCompletionBlock


operation.recordWithIDWasDeletedBlock = { (recordID, recordType) in

        //delete the core data record here
        let ckRecordToDelete = CKRecord(recordType: recordType, recordID: recordID)

        self.removeOnePatientRecordFromCoreData(ckRecord: ckRecordToDelete)

}//recordWithIDWasDeletedBlock
票数 0
EN

Stack Overflow用户

发布于 2019-06-04 07:22:47

我不太擅长斯威夫特,但我会在目标c中发布,这样你就可以把它转换成斯威夫特。

  1. 首先,如果要通知某个记录是否已被编辑、删除或创建,则需要注册推送通知。
  2. 然后订阅更新,在didFinishLaunchingWithOptions中添加此块
代码语言:javascript
复制
    - (void)subscribeToEventChanges
    {
        BOOL isSubscribed = [[NSUserDefaults standardUserDefaults] boolForKey:@"subscribedToUpdates"];
        if (isSubscribed == NO) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];

        CKQuerySubscription *subscription = [[CKQuerySubscription alloc] initWithRecordType:@"Patient" predicate:predicate options:CKQuerySubscriptionOptionsFiresOnRecordCreation | CKQueryNotificationReasonRecordDeleted | CKQueryNotificationReasonRecordUpdated];

        CKNotificationInfo *CKNotification=[[CKNotificationInfo alloc]init];
        CKNotification.shouldSendContentAvailable=YES;
        CKNotification.soundName=@"";
        subscription.notificationInfo=CKNotification;
        CKDatabase *publicDatabase = [[CKContainer containerWithIdentifier:@"your container identifir"] privateCloudDatabase];

        [publicDatabase saveSubscription:subscription completionHandler:^(CKSubscription * _Nullable subscription, NSError * _Nullable error) {
            if (error) {
                // Handle here the error
            } else {
                // Save that we have subscribed successfully to keep track and avoid trying to subscribe again
                [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"subscribedToUpdates"];
                [[NSUserDefaults standardUserDefaults] synchronize];
            }
        }];
        }
    }
  1. 您将在didReceiveRemoteNotification中收到通知

这是一段代码

代码语言:javascript
复制
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {

      CKNotification *cloudKitNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];
        if (cloudKitNotification.notificationType == CKNotificationTypeQuery) {
            CKQueryNotification *queryNotification = (CKQueryNotification *)cloudKitNotification;

            if (queryNotification.queryNotificationReason == CKQueryNotificationReasonRecordDeleted) {
                // If the record has been deleted in CloudKit then delete the local copy here

            } else {
                // If the record has been created or changed, we fetch the data from CloudKit
                CKDatabase *database;
                if (queryNotification.databaseScope) {
                    database = [[CKContainer containerWithIdentifier:@"your container identifier"] privateCloudDatabase];
                }

    [database fetchRecordWithID:queryNotification.recordID completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
                    if (error) {
                        // Handle the error here
                    } else {

                  if (queryNotification.queryNotificationReason == CKQueryNotificationReasonRecordUpdated) {
                            // Use the information in the record object to modify your local data
    }else{
                            // Use the information in the record object to create a new local object

    }



    }
            }];
     }
    }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56436270

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档