1 / 1
May 2024

We have a section of code that appears to be behaving differently on macOS vs iOS and it seems to have something to do with subscriptions but even on iOS the behavior is a little mystifying.

Here’s the section of code taken straight from the Realm Quick Start

struct OpenSyncedRealmView: View { @AsyncOpen(appId: kAppId, timeout: 4000) var asyncOpen var body: some View { let user = app?.currentUser switch asyncOpen { case .connecting: let _ = print("connecting") ProgressView() case .waitingForUser: let _ = print("waiting for user") ProgressView("Waiting for user to log in...") case .open(let realm): let _ = print("open") ItemsView(itemGroup: { if realm.objects(ItemGroup.self).count == 0 { try! realm.write { // Because we're using `ownerId` as the queryable field, we must // set the `ownerId` to equal the `user.id` when creating the object realm.add(ItemGroup(value: ["ownerId":user!.id])) } } return realm.objects(ItemGroup.self).first! }()) case .progress(let progress): let _ = print("progress") ProgressView(progress) case .error(let error): let _ = print("error") ErrorView(error: error.localizedDescription) } } }

This code works correctly on iOS but crashes on macOS within the realm.write at this line

realm.add(ItemGroup(value: ["ownerId":user!.id]))

with the following error

Cannot write to class ItemGroup when no flexible sync subscription has been created.

We then investigate the code, again copied from the Quick Start which addresses the sync subscriptions:

struct SyncContentView: View { @ObservedObject var app: RealmSwift.App var body: some View { if let user = app.currentUser { let _ = print("current user exists") let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in print("finding subs") // this never prints if let foundSubscriptions = subs.first(named: "user_groups") { print("found subscriptions") return } else { print("adding subscriptions") subs.append(QuerySubscription<ItemGroup>(name: "user_groups") { $0.ownerId == user.id }) subs.append(QuerySubscription<Item>(name: "user_items") { $0.ownerId == user.id }) } }) OpenSyncedRealmView() .environment(\.realmConfiguration, config) } else { LoginView() } } }

Now the funny thing is the code following this line

let config = user.flexibleSyncConfiguration(initialSubscriptions: { subs in

only executes once on the iOS version - right after logging in anonymously but never thereafter.

On the macOS version? It never executes at all - therefore there are no subscriptions.

Is this a difference between iOS and macOS in regards to subscriptions?