我正在构建一个严重依赖CloudKit进行数据同步的应用。每次应用程序启动时,它都会使用CKFetchNotificationChangesOperation
赶上服务器上所做的所有更改。这会成功返回已创建和/或修改过的所有对象,但我现在处于以下阶段:我还希望我的应用程序根据这些消息删除记录。
在我的应用程序中,我存储在CoreData中的每个对象也携带该对象的在线表示的recordID。这样我就可以轻松找到需要修改的对象。
删除对象时这似乎很难,因为CloudKit只返回这些对象的recordID,并且不提供我可以用来知道我在CoreData数据库中寻找什么对象的recordType。
问题
如何正确处理CloudKit'已删除'有多种记录类型的情况下的通知?
答案 0 :(得分:4)
如果CloudKit没有给出任何已删除记录类型的指示,那么处理起来就很麻烦。在不知道实体类型的情况下,您无法删除Core Data中的对象,因此如果CloudKit没有为您提供任何线索,那么您需要检查每个可能具有recordId
的实体。
删除过程与Core Data一样。使用类似`recordId =%@的谓词执行获取请求以查找匹配对象。如果找到,请删除它。除非您必须为每个潜在实体重复此操作。
可能有用的一种方法是将recordId
存储在一个新的独立实体中。创建一个名为CKRecordInfo
之类的明显新实体,并将recordId
保留在那里。具有CloudKit信息的每个其他实体都与该实体具有一对一的关系。使用此设置,您将获取新CKRecordInfo
实体的实例,并删除与其相关的任何对象。
与此同时 - 我还没有使用过CloudKit,而且它会给你只是 recordId
并且没有关于记录类型的信息,这有点令人惊讶。如果可能的话,从通知中获取信息将是理想的。
答案 1 :(得分:3)
根据您在评论中的说明,我建议您在创建订阅时配置.recordFields字典。您可以在此字典中传递有限的信息,例如记录类型。收到删除通知后,您可以从通知对象中解压缩recordFields。
您可以在https://developer.apple.com/documentation/cloudkit/ckquerynotification/1428114-recordfields
的Apple文档中找到更多信息<强>更新强>
以下是我的表现方式。我使用objective-C,因此您必须整理SWIFT语法。但步骤是:
创建我想在notif中发送的记录数组
创建订阅
创建notificationInfo对象
将我想要的键数组添加到notificationInfo对象
使用CKModifySubscriptionsOperation
NSArray *desiredKeys = @[fieldname1, fieldname1, fieldname1];
CKQuerySubscription *subscription = [[CKQuerySubscription alloc] initWithRecordType:recordName
predicate:searchConditions
subscriptionID:subscriptionID
options:fireOn];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.shouldBadge = shouldBadge;
notificationInfo.desiredKeys = desiredKeys;
subscription.notificationInfo = notificationInfo;
CKModifySubscriptionsOperation *subOp = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:subsToCreate subscriptionIDsToDelete:subsToDelete];
subOp.modifySubscriptionsCompletionBlock = ^(NSArray<CKSubscription *> *savedSubscriptions,
NSArray<NSString *> *deletedSubscriptionIDs,
NSError *operationError)
{
//do whatever
}
subOp.database = database; //set to either public or private DB
[myQueue addOperation:subOp];
当您收到通知时,只需将对象拉出notificationInfo:
NSString *value1 = [queryNotification.recordFields objectForKey:fieldname1];
如果它不允许您实际添加recordType,那么您可能必须创建一个带有记录类型指示符的自定义字段,然后按照上面的描述传递,或者通过以下方式获取相关记录使用您在通知中收到的recordID。