简体   繁体   中英

Initialize Core Data SwiftUI

I'm trying to initiate the data so when the user installs the app for the first time it has some data. The init is not working, but why?

For CRUD operations on Core Data I'm using an xcdatamodeld file with an entity called ProgrammingLanguage that has two string attributes: “name” and “creator”. Here is the code:

struct ContentView: View {

@Environment(\.managedObjectContext) var managedObjectContext

@FetchRequest(
    entity: ProgrammingLanguage.entity(),
    sortDescriptors: [
        NSSortDescriptor(keyPath: \ProgrammingLanguage.name, ascending: true),
    ]
) var languages: FetchedResults<ProgrammingLanguage>

init() {

    let language = ProgrammingLanguage(context: self.managedObjectContext)
    language.name = "SwiftUI"
    language.creator = "Some text"

    do {
        try self.managedObjectContext.save()
    } catch {
    }

}

var body: some View {
    NavigationView {
        List {
            ForEach(languages, id: \.self) { language in
                Button(action: {
                }) {
                    Text("Creator: \(language.creator ?? "Anonymous")")
                }

            }
        }
    }
}
}

It's as if it is not saving it. What's going on here? That init should create the data on the db and I would be able to read it on the view...

love seeing SwiftUI, so it seems you need to add a fetch request, it'll bring you an array of the coreData object you're looking for.

add this property right below your @Environment:

    @FetchRequest(entity: ProgrammingLanguage.entity(), sortDescriptors: []) var languages: FetchedResults<ProgrammingLanguage>

then you can present it any way you want

hope it helps, Paul Hudson has a great tutorial on CoreData and SwiftUI if you wanna watch it

https://www.hackingwithswift.com/100/swiftui/57

SwiftUI

I would recommend doing that with the .onAppear() modifier. In your code example it would be:

struct ContentView: View {
    
    @Environment(\.managedObjectContext) var managedObjectContext
    @FetchRequest(
        entity: ProgrammingLanguage.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \ProgrammingLanguage.name, ascending: true),
        ]
    ) var languages: FetchedResults<ProgrammingLanguage>
    
    
    var body: some View {
        NavigationView {
            List {
                ForEach(languages, id: \.self) { language in
                    Button(action: {
                    }) {
                        Text("Creator: \(language.creator ?? "Anonymous")")
                    }
                    
                }
            }.onAppear() {
                let language = ProgrammingLanguage(context: self.managedObjectContext)
                language.name = "SwiftUI"
                language.creator = "Some text"
                do {
                    try self.managedObjectContext.save()
                } catch let error {
                    print(error)
                }
            }
        }
    }
}

Hope that'll help: I found the solution here: Apple Developer Forum

I have a similar problem. I tried the.onAppear idea, but that doesn't work for me because in my version of Content View there are statements that require a non-empty core data -- it would need something like the UIKit viewWillAppear so that it would load the data before running any of the ContentView, which.onAppear seems not to do. I did solve the problem in another way by calling another struct that first checks if core data is instantiated, seeds the data if necessary, then calls the intended ContentView, but this seems a runaround when it is really a matter of initialization.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM