Cloud Kit Subscribe to CKRecord Created

782 views Asked by At

I have an iOS app I am working on using Cloud Kit. Basically what happens is that when a CKRecord gets deleted, the person who created the CKRecord in the first place should receive a notification. To do this, I am creating a subscription.

Everything seems to work the way it should, except it seems like whenever you create a record, you are actually subscribing to all records. Then it doesn't matter who created the record, because you will be notified. I think I am getting the NSPredicate wrong, maybe someone can help? Here is the code I have that is relevant:

    NSString *attributeName  = @"recordID";
    NSString *attributeValue = newRecord.recordID.recordName;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ like %@", attributeName, attributeValue];
    CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Photo" predicate:predicate options:CKSubscriptionOptionsFiresOnRecordDeletion];

Now I get that the attributeName for recordId actually should be something like recordID.recordName, but I tried that as well and it didn't work. I am still getting the same result. I don't know the best way to do this, but basically what I want is the subscription to fire only to the creator of the CKRecord when that record has been deleted.

Note that first I create the CKRecord, then upload it to CloudKit. Then in the callback method, I am subscribing and doing the code above.

1

There are 1 answers

5
Edwin Vermeer On

When you query a recordID field, then the attributeValue should also be a recordID and not as a string. Then for the attributeName filter you should not use %@ but %K

    NSString *attributeName  = @"recordID";
    CKRecordID *attributeValue = [[CKRecordID alloc] initWithName:newRecord.recordID.recordName];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", attributeName, attributeValue];
    CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Photo" predicate:predicate options:CKSubscriptionOptionsFiresOnRecordDeletion];

But when you have your logic like this, you will create a subscription for every record created. You could solve this by one generic subscription. Just add a condition for the metadata field creatorUserRecordID. You then do have to fetch the recordID of the loged in iCloud account first an d then create the subscription like this:

execute a fetchUserRecordIDWithCompletionHandler on the container. In the callback you will receive a recordID. just use that to create the filter

    [[CKContainer defaultContainer] fetchUserRecordIDWithCompletionHandler:^(CKRecordID *recordID, NSError *error) {
            NSString *attributeName  = @"creatorUserRecordID";
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", attributeName, recordID];
           CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Photo" predicate:predicate options:CKSubscriptionOptionsFiresOnRecordDeletion];
           // ... rest of your code
        }]

Just extend this code with error handling