Search code examples
ioscloudkit

Setting CKReference is not saved


In CloudKit dashboard, record type User has a field called Boards of type Reference (List), and record type Board has a field called User of type Reference. This is a sample of code indicating how I am attempting to link a Board to a User:

CKReference *reference = [[CKReference alloc] initWithRecord:userRecord action:CKReferenceActionDeleteSelf];
[boardRecord setObject:reference forKey:@"User"];

If I NSLog(@"%@", [boardRecord objectForKey:@"User"]); before and after setting the object, I get a result of (null) before, and after it is a CKReference object with the same recordName as the User. But in CloudKit dashboard, the Board does not update its User field, and the User does not have a reference added to its Boards reference list, so when I subsequently query the User for associated Boards I do not receive any results. I cannot understand why the reference is correctly set according to what is logged, but does not actually get saved.

Here is the code used to save to iCloud:

+ (void)saveEntity:(CloudKitEntity *)entity completion:(void (^)(NSError * _Nonnull))completion {
    [[self privateDatabase] saveRecord:entity.record completionHandler:^(CKRecord * _Nullable record, NSError * _Nullable error) {
        if (completion) {
            completion(error);
        }
    }];
}

Logging the error revealed an error that "Server Record Changed", which I think means the server version of the record is newer than the local version. But I don't know what to do about this since I have just cleaned/rebuilt, deleted the app and rebuilt/reinstalled and received the same error.


Solution

  • The solution was to fetch both of the records again using their recordIDs, then set create the CKReference and set it using the re-fetched objects, and then save the re-fetched object. Why it needs to be this complicated I have no idea.