Choosing CoreData Entities from form picker
Asked Answered
M

1

5

I have the following code:

import SwiftUI

struct LearnView: View {
    
    @State private var selectedLanguage: Language?
    @State private var selectedCategory: SubCategory?
    @State private var selectedDate = Date()
     
    @Environment(\.managedObjectContext) private var viewContext
    @FetchRequest(entity: Language.entity(), sortDescriptors: []) var languages: FetchedResults<Language>
    @FetchRequest(entity: SubCategory.entity(), sortDescriptors: []) var subCategories: FetchedResults<SubCategory>
    
    var body: some View {
        NavigationView {
            ZStack {
                Form {
                    Section("Learning Schedule") {
                        Picker("Please choose a language", selection: $selectedLanguage) {
                            ForEach(languages, id: \.self) {
                                Text($0.name ?? "Unknown")
                            }
                        }
                        Text("You selected: \(selectedLanguage?.name ?? "Unknown")")
                    }
                }
            }
        }
    }
}

I can tap on the form row, and be presented with a list of languages from the CoreData 'languages' entity. But when I tap on a language in the picker in the view that was navigated to, it doesn't place a checkmark against it and return to the form screen with my choice. It just says "Unknown" in the "You selected:" Text Field.

Language and SubCategory Entities:

Language Entity SubCategory Entity

Maitund answered 5/10, 2021 at 16:29 Comment(5)
Not having enough code to reproduce this (eg seeing Language and SubCategory), it's a little bit of a guessing game. My guess is that the Picker might be having a hard time matching the id and the selection parameter. Do the entities have explicit IDs that you can use instead of .self? And can you add them to the Text with .id()?Alvin
@Alvin I don't think the entities have explicit ID's, looking at the CoreData entity entries (which I've shown in added screenshots.Maitund
All entities (NSManagedObject subclasses) has an id from their super class named objectID so you could tag your objects using tag($0.objectID) but from my tests this doesn't help.Domingo
@Joakim Danielson Tried it, but made no difference.Maitund
Does this answer your question? How can I use Core Data value from picker? #SwiftUI #CoreDataAnthroposophy
A
6

As written you are not matching the types of the array the picker and the FetchResult. See the comments

import SwiftUI

@available(iOS 15.0, *)
struct LearnView: View {
    //This is optional Language
    @State private var selectedLanguage: Language?
    //I commented out variables that are not part of the reproducible body provided
    //@State private var selectedCategory: SubCategory?
    //@State private var selectedDate = Date()
    
    @Environment(\.managedObjectContext) private var viewContext
     //This is FetchedResults<Language>
    @FetchRequest(entity: Language.entity(), sortDescriptors: []) var languages: FetchedResults<Language>
    // @FetchRequest(entity: SubCategory.entity(), sortDescriptors: []) var subCategories: FetchedResults<SubCategory>
    
    var body: some View {
        NavigationView {
            ZStack {
                Form {
                    Section("Learning Schedule") {
                        Picker("Please choose a language", selection: $selectedLanguage) {
                            //Map is needed for a plain array of languages
                            //ForEach(languages.map{$0}, id: \.self) { language in
                            //This version works too
                            //The point is to go from FetchedResults<Language> to [Language]
                            ForEach(Array(languages), id: \.self) { language in
                                
                                Text(language.name ?? "Unknown")
                                //The casting is necessary to make it an optional since your @State is an optional
                                    .tag(language as? Language)
                            }
                        }
                        Text("You selected: \(selectedLanguage?.name ?? "Unknown")")
                    }
                }
            }
        }
    }
}

@available(iOS 15.0, *)
struct LearnView_Previews: PreviewProvider {
    static var previews: some View {
        LearnView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
    }
}
Anthroposophy answered 6/10, 2021 at 13:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.