syncing CloudKit and iCloud - ios

I have an app which currently syncs via iCloud, so the user can use the app on multiple iOS devices and has the same data everywhere.
Now I'd like to switch to CloudKit; but how is this possible if the user e.g. only updates on one device? So it's the same user, one time with CloudKit, one time still with iCloud... I guess syncing isn't possible then if I get it right?

just check if there is data in the private container. If not, then migrate and sync the data from iCloud to CloudKit. Then if he opens the app on another device then the data is already migrated to CloudKit and you can just sync that data.

Related

When using NSPersistentCloudKitContainer: what to do if the user logs out of iCloud?

From several Apple WWDC talks on CloudKit, when using CloudKit to sync private user data across devices, when the user logs out of iCloud, the App is supposed to empty the on-device cache / local replica (I use Core Data for on-device permanence). Then when this user (or any user really) logs back into his respective iCloud account on that same device, the device is then supposed to sync back down the data from the corresponding iCloud account. Makes sense!
I was wondering how I can achieve this when I use NSPersistentCloudKitContainer (instead of writing all that CloudKit code myself). I looked at the sample code related to Apple WWDC 2019 session 202 ("Using Core Data with CloudKit"), and this code does not what I want (the sample just does not focus on the iCloud account part, that is why they do not bother to empty the cache, I think): Indeed the NSPersistentCloudKitContainer stops synching if I log out the user, but it picks up again synching when I log back in. That is actually more like the desired (and indeed also actual, which is good) behaviour by the sample App when my web connection goes offline for a while.
But if the user logs out of iCloud (I use CloudKit framework to be informed about user account logout and login status), what I would need to do is somehow:
"disconnect" the sqlite store from the NSPersistentCloudKitContainer, then
empty (or even delete) the database, and then,
when the old (or another) user logs in, initialise a new NSPersistentCloudKitContainer (that will recreate an empty database as if the App would be used for the first time ever), so communication with the respective Cloud database can proceed.
I can not just empty the database WHILE being "connected" to the NSPersistentCloudKitContainer, as it records all the deletes and as soon as the (same) user logs in again, these deletes are synched to the Cloud, which I of course do NOT want.
Is this how one does it, aka essentially follow these three steps?
And if yes, how do I do step 2? Since I must use some kind of NSPersistentContainer to talk to the database, Apple warns not to directly do file system operations but only via Core Data. So do I need to init a "standard" NSPersistentContainer (without a communication pipe to the Cloud), and then destroy the database (e.g. using e.g. the coordinator instance method destroyPersistentStore())?
Or is there another approach for achieving the same thing?
Thank you very much for any help!!

Force iOS CloudKit synchronization update to download all records to local device

My app maintains a list of files locally on the iPhone. With CloudKit enabled, these files are automatically synchronized to the CloudKit database.
When the application is deleted, all the local data is also deleted. I would like to see if its possible to trigger a CloudKit notification CKNotification, specifically CKQueryNotificationReasonRecordCreated so that all my local records can be resynchronized and redownloaded.
I currently do have a function which which listens to the App delegate's didReceiveRemoteNotification, which then downloads corresponding records. However, to do so, I need to post a "fake" update so that CloudKit post a notification for it to download locally to another device.
I don't want to post a fake update for each record and would like to do a bulk download onto a local device from CloudKit.
Thank you.
I would recommend you just use CKQuery and with a given NSPredicate you will be able to get all the data you need from CloudKit database

Share database [core data] between different devices, not just the user's ones

What is the best way, to share a database between different devices, that are not just the user’s ones, but for example could be his friend’s phone. That means that iCloud is not an option.
Example:
 All of my data is app-user specific, so basically:
user logs into my app, do some work
then he can log in with the same acc on his friend phone and data should be the same
Is there an any way to upload the whole user specific database to some online storage provider (like firebase,… ) and then download it on another device and initialise core data stack, when the same user logs in on a different device?
Or is it the only way to sync data with the server and than preload the database?
You could simply upload the whole database file(s) and then download it on another device. The problem though is portability. You need to ensure that both devices support the same version of the database so they are compatible. To port the same thing to another platform is again a different story but doable when not using core data.
Then there is a problem of conflicts. Imagine you forget to log out from the second device and you open it after a week and the database is accidentally synced back to the server. This will make you lose all the data you created on your "main" device.
So in general it is possible to sync the whole thing but you will have loads of issues. You should create a server that supports all entities and works through ids (so you know the object was modified and not created) and date modified to be able to resolve conflicts.
Syncing data between multiple devices is the biggest reason to use something like Firebase. That's one of its primary purposes. You would use Firebase for data storage instead of Core Data, and it would automatically handle syncing between devices. You don't write code to upload or download anything, you just read and write Firebase data and it handles the syncing. It supports user accounts, so if a user logs on on a different device, their data automatically syncs to that device. There are numerous other options besides Firebase, of course.
CloudKit also syncs between different devices, but it's linked to the current iCloud account on the phone. Since you want in-app login, it's not so good.

How to persist core data in cloud without authentication

I am designing an app using core data which has a local Cache. I am thinking of using CloudKit for syncing it across multiple iOS devices. Since CloudKit is not for persisting data, I am pretty sure that if user loses their phone that data is gone forever. My app doesn't require any authentication so how do I save the data in cloud along with local Cache so that it can be sync across multiple iOS devices like iPad or iWatch
P.S. Is it possible to save user generated content files in Documents so that they can get backed up by iCloud automatically without using CloudKit?
The data is backed up on iTunes and iCloud periodically, so if your user changes the device then they can restore the data from there.Yes it is possible to save user generated content files in Documents so that they can get backed up by iCloud automatically without using CloudKit
As per your problem , Only creating Coredata enables you to manage data across different devices but two important question need to understand before this :
How can you preload existing data into the SQLite database?
How can you use an existing SQLite database in Xcode project?
Here is one of hot favourite tutorial for managing this :
https://www.raywenderlich.com/27657/how-to-perform-a-lightweight-core-data-migration

CoreData not storing data across multiple iOS devices

I am trying to build an iOS application using Objective C.
Where say some user is logged into my App as UserName A and they want to invite for a particular task, another user of my App ,B using their FirstName/LastName/Phone Number.
I am using Coredata to store the user credentials when they register.
The issue is : This works fine when I register both A and B from the same iOS device but NOT when I register A from iOS device 1 and B from iOS device2.
Coredata seems to store only the user data in the local device.
How can I ensure my app works for all users logged in form any iOS device ?
Core Data does not upload data to any server or synchronize data across devices. It's designed as a local-only data store. You can turn on iCloud syncing in Core Data, but this has been deprecated as of iOS 10.
If you want your app data to be available across multiple devices, you'll need to write some code to do that. Apple provides CloudKit, and there are many third party solutions. But you can't just tell Core Data to sync data, because Core Data doesn't do that.

Resources