I am a fairly new developer and I am using Xcode and Swift 5.1.
I am getting the error above when I delete a Member object from the Realm on the device that deletes it. All other devices running at the same time handle the deletion fine. I see this type of error has been asked about many times, but I don't see my case. Here is the setup:
- I have Members in a firestore database.
- I have a firestore observer that observes changes in that database and writes the changes to Realm on the device.
- In viewDidLoad in the MainVC I load the Members from Realm. And I set up a notification listener to observe changes in the Members in Realm.
- In a SettingsVC, I also also load the Members from Realm and set up a notification listener there as well.
- In the SettingsVC, I delete a Member using commit editingStyle and a google cloud function, which removes the member from the firestore database.
- My firestore observer picks up the changes and removes the Member from the Realm file.
- The listener in the SettingsVC, where the removal was done, picks up the changes in Realm and removes the Member from the tableView.
- Then it crashes with the error above.
- Note, if I have 3 simulators open at the same time and running the same version of the app, only the simulator (or device) that actually deletes the Member crashes. The other two remove the Member from the tableview and do not crash.
Here is the code found in viewDidLoad of the MainVC and the SettingsVC to load the Members and set up the notification listener:
var members:Results<Member>?
// Get the members from Realm.
UserService.loadMembers { (members) in
self.members = members
}
// Set up a listener for changes in the members.
memberNotificationToken = members?.observe { [weak self] (changes: RealmCollectionChange) in
// Make sure tableView has not been dismissed
guard let tableView = self?.tableView else { return }
tableView.reloadData()
}
}
// Turn off the listener.
deinit {
memberNotificationToken?.invalidate()
}
Here is the code in UserService.loadMembers:
static func loadMembers(completion: @escaping (_ members:Results<Member>?) -> Void) {
// Get a reference to the Realm database where the members are stored.
let realm = try! Realm()
// Get the members.
let members = realm.objects(Member.self).sorted(byKeyPath: "displayName")
// Send them back.
completion (members)
}
Here is the code to delete the Member:
UserService.deleteUser(memberToDelete: memberToDelete, completion: { status in
if status != nil {
Alerts.showBasicAlert(title: Generic Title, message: Generic message) { (alertController) in
self.present(alertController, animated: true)
}
// Reload the table.
tableView.reloadData()
}
})
})
And here is the code in the firestore observer that does the actual deleting of the member from the Realm:
// And remove deleted members.
try! realm.write {
for m in deletedMembers {
if let id = m.value(forKey: "userId"), !m.isInvalidated {
realm.delete(realm.objects(Member.self).filter("userId=%@", id))
}
}
}
Please note also that I have this exact code to manage Realm Comment objects in the MainVC and it works fine. The only difference is that with the Members, there is a second viewController that has a separate listener (i.e., the MainVC has one and the SettingsVC has one, whereas with the Comments, only the MainVC is involved for deleting the Comment and updating the table).