每个 iCloud 用户如何在 CloudKit 中保存用户特定的订阅?

How can each iCloud user save a user specific subscription in CloudKit?

我在 public CloudKit 数据库中创建订阅时遇到问题。该代码在为第一个 iCloud 用户保存订阅时工作正常,但未能尝试为第二个 iCloud 用户针对相同记录类型保存略有不同的订阅。

这是保存订阅的代码(Swift 中的答案也很好):

CKNotificationInfo *info = [[CKNotificationInfo alloc] init];
info.shouldSendContentAvailable = YES;

CKReference *ref = [[CKReference alloc] initWithRecordID:_ckUserID action:CKReferenceActionNone];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"user == %@", ref];
NSString *subId = [NSString stringWithFormat:@"access-%@", _ckUserID.recordName];

CKSubscription *sub = [[CKSubscription alloc] initWithRecordType:@"access" predicate:pred subscriptionID:subId options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate | CKSubscriptionOptionsFiresOnRecordDeletion];
sub.zoneID = [CKRecordZone defaultRecordZone].zoneID;
sub.notificationInfo = info;

CKModifySubscriptionsOperation *op = [[CKModifySubscriptionsOperation alloc] initWithSubscriptionsToSave:@[ sub ] subscriptionIDsToDelete:nil];
op.modifySubscriptionsCompletionBlock = ^(NSArray<CKSubscription *> *savedSubscriptions, NSArray<NSString *> *deletedSubscriptionIDs, NSError *operationError) {
    if (operationError) {
        RMLogError(@"Error trying to update user's access subscription: %@", operationError);
    } else {
        RMLogInfo(@"User access subscription added");
    }
};
[_ckdatabase addOperation:op];

_ckUserID 是代表当前 iCloud 用户的 CKRecordID
_ckdatbase 是对当前 CloudKit 容器的 public 数据库的 CKDatabase 引用。

当此代码在用户 A 的设备 A 上 运行 时,订阅保存得很好。

当此代码在用户 B 的设备 B 上 运行 时,订阅失败并在日志中显示以下消息:

2016-04-19 11:38:42:504 MyApp[560:f03] Error trying to update user's access subscription: <CKError 0x147830530: "Partial Failure" (2/1011); "Failed to modify some subscriptions"; uuid = 98E9F99A-C4F6-4488-8087-45285A7C1DB1; container ID = "iCloud.com.blah.MyApp"; partial errors: { access-_df09e8908eeb9b9f12ebbe935e389d51 = <CKError 0x14664b4e0: "Unknown Item" (11/2003); server message = "did not find required record type: _sub_trigger_sub_08b399dc1448e58993a967b704a07ee0"> }>

access 记录类型有一个 user 字段,它是对表示 iCloud 用户 ID 的 CKRecordID 的引用。

我的目标是为每个用户订阅,让应用知道何时添加、更新或删除了特定于当前用户的记录 table。

为什么我无法保存来自第二个用户的第二个订阅,用于此记录类型?我什至根据用户 ID 为每个订阅提供了自己的唯一 ID。

我创建了一个简单的测试应用程序来重现这个问题,当然它在我的测试应用程序中运行得很好。

我回到我的真实应用程序,经过一番挖掘后我解决了这个问题。我做了两件事:

  1. 在 CloudKit 仪表板中,我删除了所有现有的订阅类型。
  2. 我修复了我错误地将订阅的 zoneID 设置为 defaultRecordZone 的代码中的错误。虽然与已发布的问题没有真正的关系,但此错误会阻止通知到达设备,除非设备登录到用于 add/update/delete 记录的同一 iCloud 帐户。

基本上这是一些奇怪的错误,已通过重置仪表板中的某些内容并重新启动应用程序来修复。