I'm building an iOS app that heavily relies in CloudKit as a data source.
After installing the app and running it for the first time, I need to download a great amount of data that resides in the public database of my CloudKit Container. I do this with the CKFetchNotificationChangesOperation
This operation runs every time I launch the app to check for data changes since the last server change token I received. Obviously, on the first launch of the app, the change token I have to provide is nil, which would cause the CKFetchNotificationChangesOperation
to load ALL changes ever occurred on the database.
The data that is then returned will be stored locally as my desire is to have a local cache of all data relevant for my user. I store this data in a Core Data Database. As the data set the app needs when first launching might be big, I really need CKFetchNotificationChangesOperation to fetch ALL Changes on the server.\
This however, seems unreliable. When testing this service with some data I entered in my database, I don't receive all data I'm supposed to receive.
As I enter more data in my public database, the CKFetchNotificationChangesOperation
seems to completely ignore the records that I entered before. Sometimes, some slip through but it is very unreliable.
Obviously, I have verified that my subscriptions are legit (the same records got loaded before), and I have checked whether the moreComing
parameter of the CKFetchNotificationChangesOperation
is true (It is always false
)
Question
What should I do to get ALL data in my public database on an initial load? I thought that CKFetchNotificationChangesOperation
was supposed to do the job, but it seems unreliable. Is there anything like a 'scope' that I can configure on this operation to force it to load all my data? Or is CKFetchNotificationChangesOperation
not fit for initial loads and should I just load all data I need through custom operations?
Based on what I've found regarding the notification messages, it seems that the problem could be stemming from one, maybe both, of two possibilities:
Both situations can be fixed using a local storage (array or dictionary) of the records and their metadata. As described in Maintaining a Local Cache of CloudKit documentation by Apple.
Having locally stored records will allow you to populate your initial dataset, along with making any updates to changes, while waiting for any asynchronous delays through CloudKit to be finalized.
Have a local array of every NEW notificationID
that has been seen. As described in this StackQuestion Q&A, the readNotifications seem to be the reoccurring problem. Marking a notification as read prevents the notification from returning in future fetches, but they can cause issues until the CloudKit database is updated.
~~~~~~~~~~~~~~~~~~~~~~~~~ Linked Solution ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
THIS is a Stack Overflow question and answer that includes the code used to resolve a similar issue, although it does not include details as to how/why it worked. So, checkout this, one of the previous linked Q&As, that goes into a little more detail if needed.
Let me know if you have any questions, and/or want any clarification.
•••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••••
••• WWDC CloudKit Best Practices (starting around 12:45 into the vid)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With