Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not catching key errors #33

Open
bnulman opened this issue Oct 22, 2024 · 6 comments
Open

Not catching key errors #33

bnulman opened this issue Oct 22, 2024 · 6 comments

Comments

@bnulman
Copy link

bnulman commented Oct 22, 2024

Trying to incorporate this into an app I'm working on.

If I turn off iCloud for my app in iCloud settings while the app is running, the status will show as broken, though the error is "Import is broken", rather than "accountNotAvailable". However, if I force quit the app and launch it again, or if I disable iCloud prior to app launch, the status will always show as a gray cloud/"notStarted". In the console, I can see that the error is "Unable to initialize without an iCloud account (CKAccountStatusNoAccount)", but CloudSyncMonitor is not catching that.

Another problem is that it is reporting that sync has completed when actually the sync has only started and is still in progress. This is particularly an issue for large syncs that can take a while because the user thinks the sync is complete but none of their data has appeared.

@ggruen
Copy link
Owner

ggruen commented Oct 22, 2024

Hi @bnulman ,

Are you using version 3.0.0, which we just released yesterday? It has a bunch of changes, which may or may not improve the situation. If not, I'd recommend updating (see the newly updated README, which also has a lot of changes, for instructions).

One of the issues addressed in version 3.0.0 is that you need to call SyncMonitor.default.startMonitoring() as early as possible in your app's lifecycle so that SyncMonitor can subscribe to notifications from NSPersistentCloudKitContainer before it (NSPersistentCloudKitContainer) starts sending notifications. It sounds like SyncMonitor may be missing some notifications, causing it to report funky statuses for you.

That said, there are some nuances to NSPersistentCloudKitContainer that one needs to be aware of, and the primary one is that core to its design philosophy is that there is no such thing as "sync is finished" (one of Apple's senior developers made a comment to that point on developers.apple.com soon after NSPersistentCloudKitContainer's release). As such, NSPersistentCloudKitContainer's definition of "in progress" may not be what the average user (or developer) expects.

TL;DR:

In particular, NSPersistentCloudKitContainer sends a notification when an import or export starts, and another when it ends. If it hasn't, in its opinion, decided that it has started an import or export, then the sync isn't "in progress", even if the data on iCloud doesn't match the data on the user's device yet. You can see how SyncMonitor translates NSPersistentCloudKitContainer's notifications into statuses in the processSyncEvent method (currently in Sources/CloudKitSyncMonitor/SyncMonitor.swift at line 424).

@bnulman
Copy link
Author

bnulman commented Oct 24, 2024

Yes, this was with v3.0.0, and yes, I called SyncMonitor.default.startMonitoring() as early as possible.

Regarding the 2nd issue (inaccurate reporting of sync completion), I believe the problem is that there are often multiple Import (for example) operations happening simultaneously, but CloudKitSyncMonitor will report that sync is completed when the 1st operation finishes, rather than making sure that all the started operations have finished.

I solved this issue for my use case by keeping track of how many Import operations started and how many completed. Until those two numbers match, it reports that sync is in progress.

@ggruen
Copy link
Owner

ggruen commented Nov 15, 2024

Hmm, if NSPersistentCloudKitContainer is essentially sending nested notifications, then SyncMonitor isn't designed to handle that. If you made the workarounds within CloudKitSyncMonitor, could you submit a pull request?

@mgruenthal
Copy link

@bnulman,

Have you found a solution to your first issue with CKAccountStatus? I'm having the same problem, regardless of how early I start monitoring.

@bnulman
Copy link
Author

bnulman commented Dec 8, 2024

@mgruenthal, I ended up not using CloudKitMonitor and built my own solution. To solve the first problem, I check CKContainer.default().accountStatus on change of ScenePhase.

@mgruenthal
Copy link

@bnulman, Thanks. @ggruen, To recap and for others who may encounter this: When a user disables/enables iCloud for a running app, changes to iCloudAccountStatus (and therefore syncStateSummary) are not being published. The private func listenToSyncEvents() is receiving the correct CKErrorDomain Code=9 which corresponds to "CloudKit access was denied by user settings"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants