Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing CKErrorChangeTokenExpired handling by generating known expired CKServerChangeToken

The header comment on CKFetchDatabaseChangesOperation fetchDatabaseChangesCompletionBlock states:

"If the server returns a CKErrorChangeTokenExpired error, the previousServerChangeToken value was too old and the client should toss its local cache and re-fetch the changes in this record zone starting with a nil previousServerChangeToken."

I would like to test this scenario thus I would like to generate an expired CKServerChangeToken so I can set it as the previousServerChangeToken on a CKFetchDatabaseChangesOperation.

I added an init method from the private header:

@interface CKServerChangeToken (Private)
    - (id)initWithData:(NSData *)data;
@end

And used it as follows:

CKServerChangeToken knownExpiredToken = [[CKServerChangeToken alloc] initWithData:[[NSData alloc] initWithBase64EncodedString:@"AQAAAVl57tUGHv6sgNT9EeaTcQCM+sDHHA==" options:0]];

That string is a valid change token returned from a request and I have tried unsuccessfully modifying it, e.g. reducing numbers that I see incrementing to lower ones. I have however managed to get another strange invalid argument errors like continuation marker missing. I would be grateful if a CloudKit engineer has any suggestions, thanks.

like image 201
malhal Avatar asked Nov 08 '22 03:11

malhal


1 Answers

This is an old post, but I've unintentionally generated .changeTokenExpired errors by doing this:

  1. Fetch changes and save your change token.
  2. In the dashboard, delete the zone you're syncing with.
  3. Create a new zone with the same name.
  4. In your code, fetch changes again, using the change token from step 1.

Since the token refers to a different zone, it doesn't make any sense to CloudKit, which returns a .changeTokenExpired error.

like image 115
Bill Avatar answered Nov 14 '22 21:11

Bill