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)
}
}
}
}
}