Hello Everyone,
A short note first, unfortunately the following code is working, I am posting in anyway to show how the whole thing is built up. To make it executable, it still needs a CoreData table named "Person" with three columns (Id = UID, firstname = string, lastname = string).
The problem would be here, in the structure "PersonView", not when calling but when changing the detail view.
Here the changed record is simply removed from the view instead of displaying it. As long as there is no update, there is no problem.
I suppose that the problem in the original is that the @FetchRequest in PersonView is not refreshed. It could also be that the @FetchRequest uses a different managedObjectContext than the one saved.
Here are three questions:
a) How can you specify an @FetchRequest (see PersonView) which managedObjectContext it should use?
b) how could you restart the @FetchRequest when returning a detail view in PersonView
c) how could the functions load() and save() in Object DPerson be made nicer so that it doesn't look so bumpy.
As I said, the example unfortunately works, so please see it only as an illustration.
Many thanks in advance.
import SwiftUI
import CoreData
class DPerson: ObservableObject {
@Published var vorname: String = ""
@Published var nachname: String = ""
var id: UUID?
var ctx: NSManagedObjectContext?
func setContext(ctx: NSManagedObjectContext){
self.ctx = ctx
}
func load(id: UUID){
let request: NSFetchRequest<Person> = Person.fetchRequest()
request.predicate = NSPredicate(format: "id = %@", id.description)
if let m = try? ctx?.fetch(request), m.count == 1 {
self.id = m[0].id
self.vorname = m[0].vorname ?? ""
self.nachname = m[0].nachname ?? ""
}
}
func save() {
let request: NSFetchRequest<Person> = Person.fetchRequest()
request.predicate = NSPredicate(format: "id = %@", id!.description)
if let m = try? ctx?.fetch(request), m.count == 1 {
m[0].vorname = self.vorname
m[0].nachname = self.nachname
try? ctx?.save()
}
}
}
struct PersonDetail: View {
@Environment(\.managedObjectContext) var context
let personId: UUID?
@ObservedObject var dPerson: DPerson = DPerson()
var body: some View {
List{
TextField("Vorname", text: $dPerson.vorname)
TextField("Nachname", text: $dPerson.nachname)
}.onAppear(perform: {
self.dPerson.setContext(ctx: self.context)
self.dPerson.load(id: self.personId!)
})
.onDisappear(perform: {
self.dPerson.save()
})
}
}
struct ContentView: View {
@Environment(\.managedObjectContext) var context
struct PersonView: View {
var fetchRequest: FetchRequest<Person>
var body: some View {
List(fetchRequest.wrappedValue, id: \.self) { person in
NavigationLink(destination: PersonDetail(personId: person.id) ){
Text("\(person.vorname ?? "") \(person.nachname ?? "")")
}
}
}
init() {
fetchRequest = FetchRequest<Person>(entity: Person.entity(), sortDescriptors: [])
}
}
var body: some View {
VStack{
NavigationView {
PersonView()
}
Spacer()
Button(action: {
let a = Person(context: self.context)
a.id = UUID()
a.vorname = "Andy"
a.nachname = "Zacherl"
let b = Person(context: self.context)
b.id = UUID()
b.vorname = "Caro"
b.nachname = "Smith"
let c = Person(context: self.context)
c.id = UUID()
c.vorname = "Xaver"
c.nachname = "Muller"
try? self.context.save()
}) {
Text("Add DB")
}
}
}
}