Search code examples
swiftrealmcombine

Where to call freeze() when working with Realm collections and Combine?


I'd like to display some Realm objects in a read-only view (SwiftUI), and as far as I've understood, Realm objects should be frozen for such views.

But where should I call .freeze()? On the Results-object or the publisher?

Realm().objects(Contact.self)
    .freeze()
    .publisher
    .[...]

vs.

Realm().objects(Contact.self)
    .publisher
    .freeze()
    .[...]

Or does it make no difference?


Solution

  • I've just tested both variants:

    cancellable = try! Realm().objects(Contact.self)
        .freeze()
        .collectionPublisher
        .map { ... }
        .receive(on: DispatchQueue.main)
        .assertNoFailure()
        .assign(to: \.contacts, on: self)
    

    vs.

    cancellable = try! Realm().objects(Contact.self)
        .collectionPublisher
        .freeze()
        .map { ... }
        .receive(on: DispatchQueue.main)
        .assertNoFailure()
        .assign(to: \.contacts, on: self)
    

    While both variants are compiling, the first won't work: Terminating app due to uncaught exception 'RLMException', reason: 'Frozen Realms do not change and do not have change notifications.'

    Therefore freeze() has to be called on the publisher.