|
Hello, When using core data, could you please tell me what is the correct way to pass a FetchedResult Element to another view, for editing? My issue is that when I @FetchRequest and pass a specific fetched element to the next view, the subview I pass the element to reloads after I return to the Main View. Here's what I've got: A Contract element and an Invoice element in a one-to-many relationship. One contract has multiple invoices assigned to it. In the Content View, I fetch all the contract elements, and loop through them to create a list of contracts. Each row shows one specific contract, and is a NavigationLink to a detailed view of that contract. The detailed view shows attributes of the contract. I only perform a @FetchRequest in the Content View, and not in the sub-views.
The navigationLink to the DetailContract view takes a
Each individual Contract detail view also has a NavigationLink which takes me to another view, in which I show a list of invoices. Each row is an invoice signed in relation to that specific contract.
I add an invoice via a sheet I show on the Invoice list view. I enter the attributes inside the form, but when I click "save" and dismiss the sheet, the new invoice does not appear. I return to contract detail view and back to the invoice list view, and the invoice appears. The only workaround I found is dismissing both the add invoice sheet and the invoice list view at the same time when I click "save". I am not sure what I am doing wrong, but it may have to do with the fact that I perform a fetchRequest only in the content view or with the fact that the app is reloading only once I return to detail view. The problem persists if I create an .onTapGesture for each DetailView row, so that I may edit in a sheet each attribute of the element contract. If I change a row in the Detail View, the change takes effect when I return to Content View and back to Detail View. I do not have this issue when my file has only one element, with a ton of attributes. But using one single element works up to a point. Another solution would be...to perform a fetch request of all Contract elements within the DetailView or the InvoiceList view. I could fetch a filtered list of contracts...and filter the contracts using an NSPredicate, but the NSPredicate should be a contract.attribute of the contract I'm passing...which will not work, as I will get an initialization error.
I've seen Paul's video on dynamic filtering, but he's using a hardcoded string (a default string value) to filter, and not an open variable (such as @State var filter: String). Please, help :D. And please be gentle with my coding skills, as I am still learning core data. What am I doing wrong? Kind regards, Andrei |
|
Ok, so I guess a long and complicated question sometimes has a simple answer... Just pass the Entity to the next view, and wrap the entity under an ObservedObject wrapper on the next view. So in the child view in the example above, it should be Now I see why Mr Paul Hudson creates a Hope this helps someone! |
|
hi, as @andrei912 points out, the items that come from Core Data (Contract, Invoice) should be marked as one other thing: passing along a Contract as an argument to the
therefore, if you change anything involving an Invoice, please be sure to add this line before you make a change (including an insertion or deletion):
this tells the associated Contract that it has effectively changed; your (so, there's no need to have an elaborate as with @andrei912 ... hope that helps, DMG |
|
@delawaremathguy Thank you! ObservedObject and .objectWillChange.send() did the trick for me. |
BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.
Sponsor Hacking with Swift and reach the world's largest Swift community!
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.
Link copied to your pasteboard.