I’m having an issue creating subscriptions in a public CloudKit database. The code works fine when saving the subscription for the first iCloud user but fails trying to save a slightly different subscription against the same record type for a second iCloud user.
Here is the code that saves the subscription (answers in Swift are fine too):
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
is a CKRecordID
representing the current iCloud user.
_ckdatbase
is a CKDatabase
reference to the public database of the current CloudKit container.
When this code is run on Device A with User A, the subscription is saved just fine.
When this code is then run on Device B with User B, the subscription fails with the following message in the log:
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"> }>
The access
record type has a user
field that is a reference to a CKRecordID representing an iCloud user id.
My goal here is to have a subscription for each user that allows the app to know whenever a record specific to the current user is added, updated, or deleted from this table.
Why can’t I save a 2nd subscription, from a 2nd user, for this record type? I’m even giving each subscription its own unique id based on the user id.
I created a simple test app to replicate this problem and of course it worked just fine in my test app.
I went back to my real app and after some digging I got this issue resolved. I did two things:
zoneID
to the defaultRecordZone
. Though not really related to the posted problem, this bug was preventing notifications from reaching devices unless the device was logged into the same iCloud account used to add/update/delete the record.Basically this was some strange error that was fixed by resetting some things in the Dashboard and restarting the app.