Deleting a Realm Object on the Detail View in SwiftUI

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’

Is there a documented best/right way to do this?

2 Likes

I am having a similar issue

2 Likes

@ObservedRealmObjects are frozen - they need to be thawed of you want to modify them within a write.

Thanks @Jay. I know this, but I guess I wasn’t clear because it doesn’t address what I’m asking.

When you want to delete the @ObservedRealmObject while on the detail view, what’s the best practice on how to do that?

Documentation and examples are with lists, but not on the detail screen.

2 Likes

Same issue for me as well. Does Realm actually support SwiftUI, or should we start the transition to CoreData?

@Matt_Krueger Realm supports SwiftUI! - in fact there’s an entire section in the documentation just for Getting Started with SwiftUI

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?

Thanks Jay.

A couple of things:

.invalidated has been changed to .isInvalidated

You’re going to need a bang on that first thawedItem as well as in the delete.

Other than that, this seems to work. :+1:t3:

Whoops. You are so correct. I grabbed that code snippet from a project we did last year. Thanks!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.