Swiftui @Fetchrequest Core Data Changes to Relationships Don't Refresh

Updated core data values not Reflecting in SwiftUI List

Call

getTaxCodes()

When you want to see an update.

No part of your code is observing the persistent store. Your list doesn’t know when to get the new values

You completely disconnect from CoreData with the View Model and struct. If you are doing this for abstraction and not unintentionally it’s fine but you have to somehow listen to the store so you can recreate everything.

Using something in the View like onChange may or may not provide updates when needed. The store can change from many different directions that your abstraction layer will be unaware of.

This may offer you an alternative for listening.

If this is an unintentional pattern use the CoreData object directly by wrapping it with an

@ObservedObject

That way you can make changes and see them right away.

The link above also has a more direct setup for CoreData and has a simple

CoreDataPersistence

Object that does all the heavy lifting for any object.

How to update @FetchRequest, when a related Entity changes in SwiftUI?

I also struggled with this and found a very nice and clean solution:

You have to wrap the row in a separate view and use @ObservedObject in that row view on the entity.

Here's my code:

WineList:

struct WineList: View {
@FetchRequest(entity: Wine.entity(), sortDescriptors: [
NSSortDescriptor(keyPath: \Wine.name, ascending: true)
]
) var wines: FetchedResults<Wine>

var body: some View {
List(wines, id: \.id) { wine in
NavigationLink(destination: WineDetail(wine: wine)) {
WineRow(wine: wine)
}
}
.navigationBarTitle("Wines")
}
}

WineRow:

struct WineRow: View {
@ObservedObject var wine: Wine // !! @ObserveObject is the key!!!

var body: some View {
HStack {
Text(wine.name ?? "")
Spacer()
}
}
}

Changes to SwiftUI FetchRequest not triggering view refresh?

Think I figured out why this was happening. Problem is the way I was navigating to the view. Having a navigation link inside the navigation bar items was the cause. Instead I moved the navigation link outside on it's own, and replaced it with a button that controls the active state of the navigation link. Fetch Request seems to work as expected now.

Before:

.navigationBarItems(leading:
NavigationLink(
destination: MyView(),
label: {
Text("MyView")
}))

After:

NavigationLink(
destination: MyView(),
isActive: $isActive,
label: {
EmptyView()
})

.navigationBarItems(leading:
Button(
action: self.isActive = true,
label: {
Text("My View")
}))

How to prevent Core Data fetch request from resetting its predicate when SwiftUI List selection changes?

I tried your project and put in some breakpoints and the problem is when a selection is made, ContentView's body is called, which inits FruitPicker with the default FetchRequest instead of the one with the search predicate.

In looking over your coded I noticed some non-standard things. PersistenceController should be a struct not an ObservableObject (see the default app template with core data checked). The use of computed bindings looks odd to me but cool if it works.

To fix the problem you could break up the search and the list into 2 Views, so that the List is init with the new search term and then the FetchRequest will always be correct, e.g.

struct FruitPickerSearch: View {
@State var searchText = ""

var body: some View {
FruitPicker(searchText: searchText)
.searchable(text: $searchText)
.environment(\.editMode, .constant(EditMode.active))
.navigationTitle("Garden")
}
}

struct FruitPicker: View {
private var fetchRequest: FetchRequest<Fruit>
private var fruits: FetchedResults<Fruit> {
fetchRequest.wrappedValue
}

init(searchText: String){
let predicate = searchText.isEmpty ? nil : NSPredicate(format: "name CONTAINS[cd] %@", searchText)
fetchRequest = FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Fruit.name, ascending: true)],
predicate: predicate,
animation: .default)
}

var body: some View {
List(fruits) { fruit in
Text(fruit.name ?? "")
}
}
}

SwiftUI ForEach force UI update when updating the contents of a core data relationship

I’m not sure if this is the ONLY solution as @malhal gave quite an extensive and seemingly useful response.

But I came across a much easier and immediate fix, within my original solution. The inverse relationships must be specified. Doing this resolved all issues.



Related Topics



Leave a reply



Submit