I use NSPersistentCloudKitContainer to synchronize data between iOS and macOS. After installing the app, it takes long (sometimes up to an hour) for all data to become available. Related to this, I have a few questions:
Synchronization seems only to take place when the app runs in the foreground. Is there a way to keep the app synchronizing when it is brought to the background? I have enabled remote notifications and use registerForRemoteNotifications in my app delegate (via UIApplicationDelegateAdaptor). I haven't yet experimented with background processing. Should I do that, and can you point me to some references?
Is there a way to check whether the local-stored data matches what's available on the server? E.g. checking whether a (local-stored) NSPersistentHistoryToken matches the latest NSPersistentHistoryToken on the server. Internally NSPersistentCloudKitContainer knows, as I can see log events popping up saying that there are no new data to mirror. I would like to know this to inform the user that synchronization still takes place. Currently, users are complaining about missing data, which is just not available yet.
Thanks!
Post
Replies
Boosts
Views
Activity
Hello,
I am trying to show a localized image using SwiftUI's Image() by overridding the system locale like this:
.environment(\.locale, Locale.init(identifier: "nl"))
Both the preview and the actual app are still showing the default (fallback) image, not the localized version.
The image is localized in a catalog (xcassets) as described here. - https://developer.apple.com/documentation/xcode/localization/localizing_assets_in_a_catalog.
When I change my system locale (to "nl") the correct image appears.
What am I doing wrong, or is this a bug in SwiftUI?
Thanks.
I have an app that uses NSPersistentCloudKitContainer to synchronise data with iCloud. Users reported occasional data loss after which I started debugging my implementation.Part of my app’s implementation is showing a pop-up that displays information and has a confirm button. When the user clicks this button, one or more instances of a custom NSManagedObject subclass gets modified.At the same time, NSPersistentCloudKitContainer triggers a mirror process when the app resigns and becomes active. This happens when the user clicks the above mentioned confirm button. It does this by executing a NSCloudKitMirroringExportRequest and NSCloudKitMirroringImportRequest request.In other words, in my app, data gets modified (explicitly via code) and gets mirrored (implicitly via CloudKit) at the same time, and this is where things go wrong.Essentially this is what happens:1. A property (NSTimeInterval) of an instance of an NSManagedObject subclass gets incremented (e.g. 0 + 1 = 1).2. NSPersistentCloudKitContainer implicitly starts mirroring data when the app gets active or resigns.3. During this process but before it finishes, the property gets incremented again (e.g. 1 + 1 = 2).4. Internally the mirroring process finishes.At this stage I would expect the value of the property to match the latest (local) change (hence in my example 2). But instead, it matches the initial increment (hence in my example 1), overwriting my latest (local) change causing data loss. Apparently, the NSCloudKitMirroringImportRequest reverts to the state of when the mirror process started, which also can be seen in the logs:CoreData: debug: CoreData+CloudKit: -[PFCloudKitImporterZoneChangedWorkItem applyAccumulatedChanges:error:]
[…]
Importing updated records:
(
""
)At this stage I am not sure whether this is a bug in NSPersistentCloudKitContainer or my app but it definitely results in unreliable data.
Currently I have these questions:1. Why does NSPersistentCloudKitContainer (specifically as a result of NSCloudKitMirroringImportRequest) imports “updated” records while those records have only changed locally? In other words: I already have the latest version of the records. Since those “updated” records have outdated values, which overwrites my newer changes, data loss is caused. Skipping these updates from happening would solve my issue. Is there any way to control this behaviour?2. It seems like (explicitly) changing data and (implicitly) mirroring them at the same time causes issues. In my case this happens automatically due to NSPersistentCloudKitContainer scheduling the mirroring process when the app gets active or resigns. Is there any way of controlling this behaviour? Can I for example disable the mirroring process from happening when the app gets active or resigns? I noticed NSCloudKitMirroringDelegateOptions defaulting to, amongst others, automaticallyScheduleImportAndExportOperations:YES. Can I change this? And can I also trigger the mirroring process myself explicitly, at a moment when data mutation is less likely from happening?Finally, a confirmation of the above can be found in the fact that when I am not connected to the Internet (hence, CloudKit cannot mirror data), things work as expected.