CloudKit sync refresh problem when change from iOS to macOS

I am trying to test CloudKit for sync, and am testing with the Xcode (15.4) SwiftUI templates (CoreData and SwiftData variants) and also with the CKSyncEngine sample-cloudkit-sync-engine example.

I am then testing sync by running app in my MacBook and my iPhone. Generally sync is working, but the behavior is very different when syncing changes from macOS -> iOS compared to from iOS -> macOS:

  1. I open app on by my MacBook and iPhone
  2. I add item on my MacBook, it shows up a second later on iPhone
  3. On the other hand, if I add item on my iPhone it never shows up on my MacBook until I send app to background and then bring back to foreground.

Is this known/expected behavior? Any way to fix?

I assume this is a CKSyncEngine issue since the behavior is the same across all the different app setups and I think they all have CKSyncEngine in common.

For the sample-cloudkit-sync-engine example I have also tried calling try await self.database.syncEngine.fetchChanges(.init(scope: .all)) on the mac, but that doesn't seem to help. I still need to put app into background and then bring back to foreground before it will show changes.

I would expect changes to show up in my Mac UI without having to send app to background.

Answered by DTS Engineer in 789404022

Yeah, I see people reporting that CloudKit synchronization on macOS doesn't happen as quickly as it does on iOS, and that it only happens when the app comes to the foreground.

I don't think that is really a bug because CloudKit was designed to synchronize only when it determines appropriate. In this case, it is that CloudKit on macOS chooses to synchronize when your app comes to the foreground. To be very clear, bringing your app to the foreground doesn't always trigger a synchronization, because a synchronization may be throttled if the rate is too high. For more information, see:

In the production environment, that may not be a real issue, because people typically don't put their devices side by side to see the synchronization. Instead, they typically use your app on one device, and switch to another device some time later. When they switch the device and bring your app up, the synchronization happens.

If you do see that an issue in your use case, I suggest that you file a feedback report with your concrete use cases for the CloudKit team to consider.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

After two days if trying all the CloudKit demo apps that I could find and seeing same behavior... things just started to work. Now I see instant updates in both directions:

  • edit on iPhone > see on Mac
  • edit on Mac > see on iPhone

My test apps are all using different containers, but I'm doing the testing using the same user account. If anyone has insite into this change in behavior please let me know.

Odd... for and hour or so all my examples started to work. Sync was fast in both directions, but then it reverted to previous behavior... changes from Mac to iOS are fast... changes from iOS to Mac don't show until put Mac app in background and reactive. Sometimes even that doesn't work and I need to restart Mac app to see changes.

I find it very odd that even when the Mac version fails to see changes... if I add an item in the Mac version it still instantly shows up on iOS version.

Accepted Answer

Yeah, I see people reporting that CloudKit synchronization on macOS doesn't happen as quickly as it does on iOS, and that it only happens when the app comes to the foreground.

I don't think that is really a bug because CloudKit was designed to synchronize only when it determines appropriate. In this case, it is that CloudKit on macOS chooses to synchronize when your app comes to the foreground. To be very clear, bringing your app to the foreground doesn't always trigger a synchronization, because a synchronization may be throttled if the rate is too high. For more information, see:

In the production environment, that may not be a real issue, because people typically don't put their devices side by side to see the synchronization. Instead, they typically use your app on one device, and switch to another device some time later. When they switch the device and bring your app up, the synchronization happens.

If you do see that an issue in your use case, I suggest that you file a feedback report with your concrete use cases for the CloudKit team to consider.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Thanks for your reply and sorry that I didn't reply sooner.

I don't think that is really a bug because CloudKit was designed to synchronize only when it determines appropriate.

I think from end users experience perspective it would definitely be considered a bug. Please see this movie that I've made showing users experience:

To me it feels broken. Especially since changes are able to go from macOS to iOS fast... it's just changes from iOS to macOS that don't refresh until Mac app goes into background.

In the production environment, that may not be a real issue, because people typically don't put their devices side by side to see the synchronization.

While it's maybe true that users don't use Mac and iPhone at same time, there are two times when I expect this bug would be particularly problematic:

  1. Sync is often buggy and users don't trust it. So when they first get an app they will test to see if this app can actually sync well. And they do this by opening up the same document on two computer and expect consistent results.

  2. CloudKit supports data sharing with other users. Sometimes both users are editing data at same time. It will be very weird if one user (on iOS) is seeing macOS changes almost instantly, while the macOS user is seeing no changes from the iOS user.

CloudKit sync refresh problem when change from iOS to macOS
 
 
Q