Closed corysullivan closed 6 years ago
Hello @Sully73,
You're the second one to ask this question. First was @oleganza: https://twitter.com/oleganza/status/1004817666891059206
I totally lack CloudKit experience: it's difficult for me to provide a proper answer.
Maybe you can help: What do you lack today? What do you think would be desirable/possible?
I've got CloudKit integration for LocoKit's GRDB layer. But that code isn't open source (yet?).
The very short version is you want to use CloudKit subscriptions for observing changes from the CloudKit side, and on the GRDB side you want to have some extra fields on your tables, for knowing when the rows need to be saved/updated to CloudKit.
protocol CKObject: PersistentObject {
var ckRecord: CKRecord? { get set }
var ckRecordName: String? { get set }
var ckLastSaved: Date? { get set }
}
That's part of the protocol I use, which my database models implement. The ckRecordName
and ckLastSaved
allow you to know whether the object needs updating on CloudKit or not. Uh, you also need to keep a lastSaved
field for knowing when the row was last updated on the GRDB side.
Yeah, there's a fair bit involved in it. This is only scratching the surface really, and I don't have the time to write up a proper howto just now, unfortunately.
I recommend hunting around for a generalised tutorial on the process, as it should be the same as for any other database layer. The patterns are fairly universal.
I also second the support for CloudKit. For the moment, the only thing preventing me from using GRDB(and leave Core Data behind) is the lack of cloud sync.
I’ve done my own CloudKit integration where iCloud is the truth and GRDB serves as a local cache, sync’ing with the cloud. Although I do have some experience with CloudKit, I haven’t taken the time and effort to think about how GRDB could generally support or integrate with CloudKit. I simply can’t envision a good general-purpose API for it on the spot.
The fact that GRDB is so focused on local persistence is also one of its strengths. If I could just tick a checkbox to get a magical CloudKit integration, I wouldn’t complain, of course :-)
Hello @zrfrank and @osteslag. The plain truth is that I haven't used CloudKit yet, so my own ideas are pretty fuzzy: https://twitter.com/groue/status/1263135372743184391
My main message to anybody listening is that a much welcomed contribution would be to define what "CloudKit support" could mean for an SQLite wrapper like GRDB. What are the desired use cases? Is it only a matter of implementing a new set of APIs, or would it require modifications in the existing GRDB layers (SQL, records, query builder)?
Finally, I suggest having a look at https://github.com/mentrena/SyncKit "Automatic CloudKit synchronization". I don't quite know what it does exactly, but this library which is well supported can drive both Core Data and Realm through plugins. Maybe it is possible to develop a GRDB plugin for SyncKit?
cc @mentrena
I think the use case mentioned by @osteslag, "iCloud is the truth and GRDB serves as a local cache, sync’ing with the cloud", would be a very typical one. In such case,
For example, a "magical integration" could be, an update on an iPhone, could trigger the update on iPad and macOS, i.e. the database is completely in-sync across devices.
Naively, I would guess such integration would require a synchronization layer managing,
A further and probably non-realistic idea is that, as GRDB is entirely backed by SQLite and any app that's using GRDB is designed with SQLite in-mind, GRDB can just synchronize a pip-line of the SQL transactions?
@groue I'm not familiar with GRDB myself, but I can say the approach suggested by @zrfrank is precisely what I use in SyncKit.
I have a synchronisation layer that deals with CloudKit and fetches changes incrementally using CKFetchRecordZoneChangesOperation
and other CloudKit operations.
And then there's a model adapter layer that deals with translating CKRecord
s to model objects and also tracking changes to the local model and providing the former layer with CKRecord
s to upload those changes to CloudKit.
Currently I provide model adapters for Core Data and Realm, but I suppose it should be possible to create a new one for GRDB (Would need a new class conforming to https://github.com/mentrena/SyncKit/blob/master/SyncKit/Classes/QSSynchronizer/ModelAdapter.swift). If that's something you'd like to look into I'd be happy to help (not sure I'd have time to do it myself short-term)
Another solution you might find worth looking at, although I haven't personally used it, is https://github.com/caiyue1993/IceCream
Dear Gwendal,
GRDB is now well settled in my Patients app. I was reading on syncing via CloudKit of my SQLite database. The idea is to leave the refreshing of data to running my app on my Mac and treat my iPad and iPhone as read-only devices.
I found an interesting Github entry that does SQLite syncing over Cloudkit on top of GRDB! Take a look at gerdemb/SQLiteChangeSetSync on Github.
Regard, André Hartman
Hello @ahartman,
I'm happy with leaving the CloudKit sync facet to the community. The current GRDB apis should not prevent anyone from building their CloudKit sync solution. And I don't myself have any interest in CloudKit, whereas a robust implementation requires a lot of dedication and tests.
Have a look at https://github.com/aaronpearce/Harmony: it provides CloudKit sync for GRDB.
Hi everyone, sorry to bother you. I would like to leave some comments for future viewers who want to support CloudKit for GRDB.
If you only need to support iOS 17 or newer, you can use the CKSyncEngine
, Jordan Morgan has a great article talking about how to use it.
The key part is translating GRDB record to theCKRecord
, for this part you can check Harmony's code.
Any plans to integrate with CloudKit? or any references/guides on how to achieve this?