WWDC24 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: List Fails to Update when Detail Saved (Core Data)

Forums > SwiftUI

I'm lost and have been searching these forums (and Google) for hours.

I have a pretty straightforward Core Data class with a custom extension for making the fetch simpler. (Thanks to Donny Wals!)

extension Item {
  static var defaultFetchRequest: NSFetchRequest<Item> {
    let request: NSFetchRequest<Item> = Item.fetchRequest()
    request.sortDescriptors = [NSSortDescriptor(keyPath: \Item.sort_title, ascending: true), NSSortDescriptor(key: "title", ascending: true)]
    return request
  }
}

That works perfectly fine (as far as I can tell) in a List View:

struct ItemsView: View {

    @FetchRequest(fetchRequest: Item.defaultFetchRequest)
    var items: FetchedResults<Item>

    var body: some View {
        NavigationView{
                    List(items, id: \.self){ item in
                        ZStack{
                            ItemCellView(item: item)
                            NavigationLink(destination: ItemDetailView(item: item)) {
                                EmptyView()
                            }
                        }
                    }
        }
    }
}

My Item Detail View works fine (again, as far as I can tell) and I know its self.moc.save() does save because (a) when I return to the list and then return to the detail, the changed data is there and (b) when I close and reopen the app in Simulator, the primary list shows the data change.

The problem is that unless I quit and restart the Simulator, the main list does not refresh. When I save() in the detail view and return to the main list, the list doesn't display the changes. Again, though, I know the changes were made because they are there when I stop and restart the app in Simulator.

Do I need to do something to make the FetchedResults<item> "listen" for changes? In UIKit I'd do a reload the table on viewDidAppear, but that seems contrary to SwiftUIness. Can anyone tell me what I'm missing here?

  • Note that I've removed a bunch of extraneous code for styles, padding, etc.

4      

No, really. This is driving me absolutely crazy. I've tried multiple versions of Paul's implementations, and blckbird's version and ones I've found on Medium and StackOverflow and even reddit. I don't understand what I'm doing wrong here. Could it be because I have an ItemCellView in the List?

Update: Wow. Yes, that was it. I swapped ItemCellView(item: item) for a simple Text(item.title) and now it's working.

Well, fudge. How / why does the ItemCellView not get updated dynamically?

3      

@DavidGagne Just something to check. In your ItemCellView, is item:

  • a plain var or
  • an @ObservedObject var

If it's not an @ObservedObject, change it and see if it works. @ObservedObject adds @Published to properties in your class, such at your title property so it should get updated.(https://www.hackingwithswift.com/quick-start/swiftui/how-to-use-observedobject-to-manage-state-from-external-objects)

Hope this works and helps

5      

Hot damn, @thacarus130! That worked.

I simply added @ObservedObject to my item in ItemCellView and changed it from a let to a var, and it worked!

5      

Save 50% in my WWDC sale.

SAVE 50% To celebrate WWDC24, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.