Search code examples
swiftuiswiftui-form

Setting a default value for an NSManagedObject in SwiftUI Picker?


I'm working with Picker in SwiftUI to choose from a list of Core Data NSManagedObjects, and can't get the picker to display a default value. It also won't set a new value after one is chosen. Is there a way to have a default value for the picker to display?

Here's where the properties for my NSManagedObject are set up.

extension Company {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<Company> {
        return NSFetchRequest<Company>(entityName: "Company")
    }

    @NSManaged public var id: UUID?
    @NSManaged public var name: String?
    @NSManaged public var companyContacts: NSSet?
    @NSManaged public var companyRoles: NSSet?

    //...

}

And here's where I'm trying to use it.

struct AddRoleSheet: View {
    @Environment(\.managedObjectContext) var moc
    @FetchRequest(
        entity: Company.entity(),
        sortDescriptors: [
            NSSortDescriptor(keyPath: \Company.name, ascending: true)
        ]
    ) var companies: FetchedResults<Company>

//...

@State var company: Company? = // Can I put something here? Would this solve my problem?

//...

var body: some View {
    NavigationView {
        Form {
            Section {
                Picker(selection: $company, label: Text("Company")) {
                    List {
                        ForEach(companies, id: \.self) { company in
                            company.name.map(Text.init)
                        }
                    }
                }
                //...
            }
        }
        //...
    }
}

Solution

  • There is no fetched results on View.init phase yet, so try the following

    @State var company: Company? = nil   // << just initialize
    
    //...
    
    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker(selection: $company, label: Text("Company")) {
                        List {
                            ForEach(companies, id: \.self) { company in
                                company.name.map(Text.init)
                            }
                        }
                    }
                    //...
                }
            }
        }.onAppear {
           // here companies already fetched from database
           self.company = self.companies.first      // << assign any needed
        }
    }