I’m running into an issue where I want to allow for the deletion of an object on the screen that is showing the details.
Example:
struct ItemsList: View {
@ObservedResults(Item.self) var items
var body: some View {
ForEach(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
Text(item.name)
}
}
}
struct ItemDetailView: View {
@ObservedRealmObject var item: Item
@Environment(\.realm) var realm
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
var body: some View {
VStack{
Text(item.name)
Image(systemName: "trash")
.onTapGesture{
// delete the item
realm.asyncWrite{
realm.delete(item)
}
// pop back so as not to show the detail view anymore since it doesn't exist
self.presentationMode.wrappedVaule.dismiss()
}
}
}
}
This is an oversimplified version of what I’m doing, but I can’t find anything in the docs that shows how to do this the “right” way, and I’m posting it here because I do assume it is a pretty common use case.
I keep trying different strategies (thawing, passing the object back up the stack and deleting on the top screen, asnycWrite/write, etc.) and I happen to be getting this error a lot, but I don’t understand what it means:
‘This method may only be called on RLMArray instances retrieved from an RLMRealm’
The ‘detail’ view vs the ‘main’ view vs any other view doesn’t really factor in to how you work with Realm. What does factor in is what types of (and how) objects are being passed around to those views; are you passing an object? Is it an Environment value? Or perhaps it’s the realm itself to when you can then read the object in question.
So there is no ‘right way’ because it depends on the status of the object.
It appears in this, based on your example code, the object is frozen, so thawing it would allow deletion.
But - that leads to a question; are you wanting to delete the object from it’s parent objects List or delete the object entirely from Realm, never to be heard from again?
Here’s some example code we use in other views to delete an ObservedRealmObject
let thawedItem = item.thaw()
if thawedItem.invalidated == false { //ensure it's a valid item
let thawedRealm = thawedItem!.realm! //get the realm it belongs to
try! thawedRealm.write {
thawedRealm.delete(thawedItem)
}
}
I added the code in your question to a project and it seems to work - I am not getting the mentioned error so perhaps it’s thrown by another section of code?