Post

Replies

Boosts

Views

Activity

How to handle CloudKit remote notifications for local changes?
So in my app, I have a Core Data store. I want to add a sync feature to synchronize the data in the Core Data store between the user's iOS devices with CloudKit. Unfortunately, the feature Core Data with CloudKit that was introduced in 2019 doesn't meet my requirements, since it's more or less a blackbox, and I do have some other files in the storage (on disk) to sync as well that are outside the Core Data store. Besides those, I want to support older iOS versions, like iOS 10 to 12. So that's another reason I can't use Core Data with CloudKit. I decided to implement my own version of it. I've been following the "Maintaining a Local Cache of CloudKit Records" https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitQuickStart/MaintainingaLocalCacheofCloudKitRecords/MaintainingaLocalCacheofCloudKitRecords.html#//apple_ref/doc/uid/TP40014987-CH12-SW1 So the problem that I've been seeing with is handling remote notifications for local changes. Specifically, during my testing, I realized an indefinite sync loop: User updates some data to Core Data and files to disk on Device A; Core Data changes and the updated files are converted into CKRecords and CKAssets; CKRecords and CKAssets are sent to CloudKit server; CloudKit server receives the changes and sends out silent, remote notifications to Device A (and Device B); The app on Device A receives the notification and tries to fetch database changes and zone changes; The CKRecords are converted back into NSManagedObjects, which are then stored in Core Data; New changes in Core Data detected, and Step 2; For now, my solution is to break the loop in Step 5: Before trying to convert CKRecords back into NSManagedObjects, I check if the recordChangeTag of the CKRecords sent from the server is the same as the one in the cached CKRecords when they were saved previously. I don't see a better solution so far. And since the CKAsset is a field of the CKRecord, downloading the asset I already have locally in Step 5 seems to take a lot of time and unnecessary, especially if the CKAsset is a large file. An alternative I can think of is to break the CKRecord apart and use a CKReference to another CKRecord which has the CKAsset as a field. Am I missing anything important? Any help would be appreciated.
1
0
820
Dec ’20