Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CloudKit: CKFetchRecordChangesOperation, CKServerChangeToken and Delta Download

My question is related to the "Delta Download" thing as it was named in WWDC 2014 Advanced CloudKit.

I'm trying to make syncronization for my Core Data app, which is iPhone only for now (think: there is only one device active). So, basically the app will store user records in the cloud from one same device, for the most cases for now.

I have trouble with understanding custom zone feature which is based on CKFetchRecordChangesOperation aka Delta Download.

As I got it right, we have CKServerChangeToken's to maintain sync operations (I mean download only those records which was added/modified/deleted by another device), as was presented on WWDC. But, what I can't understand is that we recieve that token only after CKFetchRecordChangesOperation, when we save records to the cloud we don't get new token.

And if we make fetch with the current available token (since it changes only after fetch), we recieve records that was saved from our previous save operation. Basicaly we get save recods that already have on our device. Why? I'm missing something here?

What if we seeding some data to the cloud (from device A), it is justified for situation when device B is fetching the zone records, but what if device A be? Download all the records again?

I found recordChangeTag in the CKRecord, is this a property I can use for resolving conflicts with local objects - fetched objects (same or different version), if so can somebody give me example of how I need to do this: save recordChangeTag to Core Data when save record to CloudKit for the first time or how?

The lack of documentation is such a headache.

like image 901
Dima Deplov Avatar asked May 05 '16 23:05

Dima Deplov


1 Answers

I found a time to write an answer for this question. I won't dig into implementation, but I will discuss the concept.

CloudKit provides a way to data synchronisation between your device and the CloudKit server. What I use to establish synchronisation process in my case between iPhone and server only (again, if you have iPhone + iPad app, the process require more steps.):

I have custom zone in the private cloud database. I use OperationQueue to establish different asynchronous processes which depend on each other. Some operations have own operation queues.

Steps:

1) Check if my custom zone is exist

1.1) If there is no custom zone

1.2) Create new custom zone. (Optional: add records)

1.3) Refresh zone change token

You can refresh zone change token by: performing CKFetchRecordChangesOperation, fetchRecordChangesCompletionBlock returns CKServerChangeToken save it to UserDefaults (for example) using NSKeyedArchiver). This operation's task is to refresh token and it's performed at the end synchronisation process.

2) If there is custom zone already

2.1) Get changes from zone using previously saved zone change token. (CKFetchRecordChangesOperation)

2.2) Update and delete local records.

2.3) Refresh zone change token.

2.4) Check for local changes (I'm using last cloud sync timestamp to check what records was modified after).

2.5) Upload records to cloud kit database

2.6) Refresh zone change token again.

I highly recommend Nick Harris article series: https://nickharris.wordpress.com/2016/02/09/cloudkit-core-data-nsoperations-introduction/

You'll find there implementation and design concepts. It worth reading. I hope somebody'll find all of this helpful.

like image 127
Dima Deplov Avatar answered Sep 21 '22 09:09

Dima Deplov