RealmSwift: @ObservedResults not updating with Realm Sync

I’m trying to use Realm Sync for a basic CRUD app using SwiftUI, but for some reason the ObservedResults property wrapper is not updating my view when I add/delete objects.

The Realm App is set up on the free shared tier. When I insert/delete entries, I can see in the Realm App logs that the data is being inserted/deleted appropriately in the collection. The problem is that the SwiftUI View (using the ObservedResults wrapper) does not update appropriately. On the other hand, if I quit and restart the iOS app, any insertions/deletions I’ve made DO show up.

Any clue what I could be doing wrong? (I was having the same problem before I switched to using the AsyncOpen wrapper, if that helps.)

Relevant portions of code:

let app = RealmSwift.App(id: "cmrepositoryapp-snjjs")

class AppState: ObservableObject {
    @Published var userID: String?
}

@main
struct RepositoryRealm_App: SwiftUI.App {
    @StateObject var appState = AppState()
    var body: some Scene {
        WindowGroup {
            switch appState.userID {
            case nil:
                Text("XXXX")
                    .onAppear {
                        switch app.currentUser {
                        case nil:
                            app.login(credentials: .anonymous) { result in
                                DispatchQueue.main.async {
                                    switch result {
                                    case .failure(let error):
                                        fatalError(error.localizedDescription)
                                    case .success(let user):
                                        let partitionValue = user.id
                                        appState.userID = partitionValue
                                    }
                                }
                            }
                            
                        case let currentUser?:
                            let partitionValue = currentUser.id
                            appState.userID = partitionValue
                        }
                    }
                
            case let userID:
                ContentView()
                    .environmentObject(appState)
                    .environment(\.partitionValue, userID)
            }
        }
    }
}

struct ContentView: View {
    @AsyncOpen(appId: "cmrepositoryapp-snjjs", partitionValue: "", timeout: 5000) var asyncOpen
    var body: some View {
        switch asyncOpen {
        case .connecting:
            Text("Connecting...")
        case .waitingForUser:
            Text("Waiting for user...")
        case .open(let userRealm):
            EntryObjectListView()
                .environment(\.realm, userRealm)
        case .progress(let progress):
            ProgressView(progress)
        case .error(let error):
            fatalError(error.localizedDescription)
        }
    }
}

struct EntryObjectListView: View {
    @EnvironmentObject var appState: AppState
    @ObservedResults(EntryObject.self) var entryObjects
    
    var body: some View {
        NavigationView {
            VStack {

                List {
                    ForEach(entryObjects) { entryObject in
                        Text(entryObject.title)
                    }
                    .onDelete(perform: $entryObjects.remove)
                }
                Spacer()
                Button("add text", systemImage: "plus") {

                    let entryObject = EntryObject(dataType: TextData.self)
                    entryObject.title = "hello text!"
                    entryObject._partition = appState.userID!

                    $entryObjects.append(entryObject)
                }
                Button("delete all", systemImage: "minus") {
                    withAnimation {
                        for entryObject in entryObjects {
                            $entryObjects.remove(entryObject)
                        }
                    }
                }
                Button("print count", systemImage: "minus") {
                    print(entryObjects.count)
                }
            }
        }
    }
}

Could you please file a GitHub issue on this? I believe this is a legitimate bug due to how SwiftUI3 conducts observation.

1 Like

https://github.com/realm/realm-cocoa/issues/7447

Oddly, if I close the app (returning to the iPhone home screen) and then reopen it, the bug is gone, and the SwiftUI view with the @ObservedResults wrapper works as expected.