realm-swift icon indicating copy to clipboard operation
realm-swift copied to clipboard

Consider implementing a SwiftData Custom Store (new in iOS18) for Realm

Open clarkezone opened this issue 1 year ago • 12 comments

Problem

Right now I'm using SwiftData along with SwiftUI in an iOS app and wish to add cloud sync. The only choice in iOS17 is to use Apple's default CloudKit store for SwiftData which has some serious problems for production, primarily lack of support for unique constraints which to duplicate records for multi-device scenarios that is not easily solvable. This problem is specific to the CloudKit backend, not SwiftData itself which fully supports both a per property @Attribute(.unique) var name: String as well as compound (new in iOS18) attributes: @Model class Trip { #Unique<Trip>([\.name, \.startDate, \.endDate]) I really want to use Realm although realm doesn't support watchOS currently which is a separate issue.

That aside, if Realm could plug in to SwiftData I'd be able to have the best of both worlds.

Solution

In iOS18 apple is introducing a provider model for stores as shown in this talk https://developer.apple.com/wwdc24/10138 and described in what's new in their docs: https://developer.apple.com/documentation/Updates/SwiftData. If realm supports this it will provide an easy, compatible on-ramp to realm for SwiftData users like me.

Alternatives

I could adopt the Realm iOS SDK but that paints me into a corner I don't want to be trapped in. Whichever cloud provider is first to support SwiftData for a data sync will be my first choice. I hope that's Realm.

How important is this improvement for you?

Dealbreaker

Feature would mainly be used with

Atlas Device Sync

clarkezone avatar Jun 16 '24 22:06 clarkezone

➤ PM Bot commented:

Jira ticket: RCOCOA-2390

sync-by-unito[bot] avatar Jun 16 '24 22:06 sync-by-unito[bot]

I don't think Realm is a good candidate for this. The example that Apple gave for this custom storage engine was a JSON file. "Translating" Realm's storage engine to SwiftData on-the-fly seems like it would destroy many features: live objects, lazy-loading of the data behind objects, etc. And the extra layer of abstraction seems like it would murder performance and make debugging even more of a nightmare.

The sad reality is that Apple screwed up. They should have bought Realm before Mongo did and they should have integrated it as a first-party replacement for Core Data. They should have recognized that, in the modern world, developers want a data persistence framework that is available EVERYWHERE--not just on Apple platforms.

Tying yourself to SwiftData is a mistake. You're hamstrung to Apple's platforms, you'll get updates and bug fixes exactly once per year, at WWDC, and most of those will be unusable for a long time because you'll have to target a new version of iOS/macOS/watchOS, but your users won't be on that version of the platform for years.

By contrast, Realm updates every few weeks, you can adopt those updates immediately, and you're never tied to a single platform--use Realm anywhere you want; there are SDKs for everything.

Kick Apple's data persistence nonsense to the curb.

bdkjones avatar Jun 18 '24 17:06 bdkjones

My RealmSwift-using code has zero portability so I'm not sure what you mean about multi platform availability being key?

aehlke avatar Jun 18 '24 19:06 aehlke

@aehlke Let's say you have a simple "todo" app. You want to create an iOS version, an Android version, and a web app version. If you use Swift Data and CloudKit for your app, good luck building on the latter two platforms. By contrast, Realm has an SDK for each and it talks to the same source of truth in the cloud.

bdkjones avatar Jun 18 '24 19:06 bdkjones

Oh I see - I don't use Realm's cloud services (I have Realm automatically background syncing with CloudKit + my own servers)

I'm hoping https://skip.tools prioritizes the ticket for porting RealmSwift usage to Android

aehlke avatar Jun 18 '24 21:06 aehlke

+1 It would be great to be able to use native SwiftData with Mongo backend without having to integrate the heavy Realm SDK in the future :)

bioche avatar Jul 09 '24 21:07 bioche

  • 1, any news on this?

alelordelo avatar Jul 31 '24 18:07 alelordelo

Btw I'm working on combining IceCream and SyncKit into lake-of-fire/BigSyncKit and updating to latest everything. It's a WIP but I'm full time on trying to stabilize it now. It gives CloudKit sync for Realm for free.

aehlke avatar Aug 03 '24 13:08 aehlke

Btw I'm working on combining IceCream and SyncKit into lake-of-fire/BigSyncKit and updating to latest everything. It's a WIP but I'm full time on trying to stabilize it now. It gives CloudKit sync for Realm for free.

hi @aehlke I had a look on your library, but if I understand correctly its Realm locally + cloud kit as the backend server sync?

My main issue now is that I am heavily using @Observable, and then saving to realm. This creates a huge complexity on things... Local Model- Realm Server - MongoDB VM - @Observable View - SwiftUI

The ideal would be to use easily migrate @Observable to SwiftData @Model and remove Realm, but then you are stuck with CloudKit for sync, which is prohibitive for multi user collaborative apps. So this is why this custom SwiftData backend make a lot of sense:

Model/VM- SwiftData Server - MongoDB View - SwiftUI

This cold be done using: The SwiftData -> JSON ->Mongo

As mentioned here: https://developer.apple.com/videos/play/wwdc2024/10138/

alelordelo avatar Aug 03 '24 14:08 alelordelo

I don't think Realm is a good candidate for this. The example that Apple gave for this custom storage engine was a JSON file. "Translating" Realm's storage engine to SwiftData on-the-fly seems like it would destroy many features: live objects, lazy-loading of the data behind objects, etc. And the extra layer of abstraction seems like it would murder performance and make debugging even more of a nightmare.

The sad reality is that Apple screwed up. They should have bought Realm before Mongo did and they should have integrated it as a first-party replacement for Core Data. They should have recognized that, in the modern world, developers want a data persistence framework that is available EVERYWHERE--not just on Apple platforms.

Tying yourself to SwiftData is a mistake. You're hamstrung to Apple's platforms, you'll get updates and bug fixes exactly once per year, at WWDC, and most of those will be unusable for a long time because you'll have to target a new version of iOS/macOS/watchOS, but your users won't be on that version of the platform for years.

By contrast, Realm updates every few weeks, you can adopt those updates immediately, and you're never tied to a single platform--use Realm anywhere you want; there are SDKs for everything.

Kick Apple's data persistence nonsense to the curb.

This hasn't aged well... Realm kicked to the curb !

duncangroenewald avatar Oct 09 '24 10:10 duncangroenewald

Btw I'm working on combining IceCream and SyncKit into lake-of-fire/BigSyncKit and updating to latest everything. It's a WIP but I'm full time on trying to stabilize it now. It gives CloudKit sync for Realm for free.

Did you ever get this working, @aehlke ?

clarkezone avatar Jan 28 '25 20:01 clarkezone

@clarkezone it's a work in progress here https://github.com/lake-of-fire/BigSyncKit and it's shipped in the app Manabi Reader if you want to test it. I recently made it much more performant by allowing to remove use of changesetPublisher by using polling for changed data via modifiedAt & createdAt fields in an optional protocol you conform to as I found Realm was horribly slow at calculating changesetPublisher diffs on every write

If I were to redo it today I'd consider using the iOS 17 (IIRC) tools Apple added for doing CloudKit sync more easily for any data backend but that's also not trivial

aehlke avatar Jan 29 '25 16:01 aehlke