Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: CKFetchNotificationChangesOperation results incomplete

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?

like image 577
Joris416 Avatar asked Aug 31 '17 12:08

Joris416


1 Answers

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:

  • Records are being stored asynchronously, providing an unintended delay when populating local datasets.
  • Read notifications are muddling the desired query/subscription results.

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.

Situation 1:

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.

Situation 2:

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)

like image 191
ChrisHaze Avatar answered Oct 14 '22 16:10

ChrisHaze