CoreData + CloudKit synchronization is very unstable & unreliable

CloudKit sync is very unstable. Sometimes it just stops syncing for no reason, other times it works almost instantly.

The core issue with synchronization is that CoreData relies mostly on two things:

  • silent push notifications, which are by design unreliable and can be throttled
  • user interactions, I noticed that the local database is updated most likely periodically and also based on some app events like entering the foreground.

Unfortunately, there is no SDK function that allows us to force sync with CloudKit, which basically prevents us from providing some features to recover if a user encounters problems.

After thousands of tests, I finally discovered what was wrong and how to make the synchronization stable. Basically, I noticed that at some point CoreData decides that it won't synchronize data unless you deactivate and activate the application, which is crazy. It's getting even worse if we talk about extensions like the keyboard extension on iOS. The same happens on all platforms.

Therefore, knowing that I implemented a trick that happened to work perfectly. The workaround requires to periodically sending an event pretending that the app is going foreground.

macOS:

var cancellable = Set<AnyCancellable>()
// ...
Timer.publish(every: 20.0, on: RunLoop.main, in: .common)
  .autoconnect()
  .sink { _ in 
     NotificationCenter.default.post(.init(name: NSApplication.willBecomeActiveNotification)) 
  }
  .store(in: &cancellable)

iOS:

var cancellable = Set<AnyCancellable>()
// ...
Timer.publish(every: 20.0, on: RunLoop.main, in: .common)
  .autoconnect()
  .sink { _ in 
     NotificationCenter.default.post(.init(name: UIApplication.didBecomeActiveNotification)) 
  }
  .store(in: &cancellable)

After that, everything works perfectly. Pitty that the solution mostly meant for enterprise is so unstable and there is not even a single SDK function to recover from that (force sync).

Any plans to fix CoreData+CloudKit? I also created a ticket: #FB14531806.

Answered by DTS Engineer in 798336022

CloudKit sync is very unstable. Sometimes it just stops syncing for no reason, other times it works almost instantly.

When CoreData + CloudKit stops syncing, it can be that the system intentionally throttles the synchronization to balance the use of system resources and achieve the best overall user experience on the devices. To determine if that is the case and understand how the system works, you might want to read through the following technotes:

I also created a ticket: #FB14531806.

Thanks for filing the feedback report. To investigate the issue, we would need to gather more information. If you don't mind, please follow the Provide actionable feedback section to gather the appropriate information and use it to update your feedback report. That would be a great help for the team's investigation.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

CloudKit sync is very unstable. Sometimes it just stops syncing for no reason, other times it works almost instantly.

When CoreData + CloudKit stops syncing, it can be that the system intentionally throttles the synchronization to balance the use of system resources and achieve the best overall user experience on the devices. To determine if that is the case and understand how the system works, you might want to read through the following technotes:

I also created a ticket: #FB14531806.

Thanks for filing the feedback report. To investigate the issue, we would need to gather more information. If you don't mind, please follow the Provide actionable feedback section to gather the appropriate information and use it to update your feedback report. That would be a great help for the team's investigation.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Just a hint for others: if you use a Panel(which doesn't take over the focus) as your main app window on macOS, make sure that it triggers NSApplication.willBecomeActiveNotification.

Otherwise, the synchronization will be completely broken as the CloudKit SDK mainly awaits activation notifications, which are not sent if the app doesn't capture the focus.

Often neither the export nor import will work in this case, unless you open some other, regular window. The best solution at this point is to use the workaround that I posted and send manually activation events periodically (I'm curious if it's not going to generate tons of fake analytics).

For now, the synchronization is unreliable unless you send those events manually, we have to wait for a fix.

CoreData + CloudKit synchronization is very unstable &amp; unreliable
 
 
Q