SwiftUI TextField passing a default text value

I am trying to integrate SwiftUI into a new app that uses CoreData model objects. I would like to show the properties of these objects in a custom SwiftUI component that has the text property of the TextField defaulted to the current value of that attribute.


Would be so greatful for any insights on how best to implement this.


Should the CoreData NSManagedObjects be passed in the View heirarchy as @ObservedObjects (in order to bind the value to the TextField)? I've been trying this and seem to run into issues where the compiler doesn't recognize the arguments as valid. The below code does not compile, I get an error 'Type '_' has no member 'testFieldId' on Line 8 of TestView.


Here's a 'Test' NSManagedObject:

import Foundation
import CoreData

@objc(Test)

public class Test: NSManagedObject, Identifiable, Encodable {

    @NSManaged public var name: String?
    @NSManaged public var sampleTestId: String?
    @NSManaged public var tabNumber: Int16
    @NSManaged public var sample: Sample?
    @NSManaged public var testFields: NSOrderedSet?
    
    enum CodingKeys: String, CodingKey {
        case name
        case sampleTestId
        case tabNumber
        case sample
    }
    
    // MARK: - Encodable
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(sampleTestId, forKey: .sampleTestId)
        try container.encode(name, forKey: .name)
        try container.encode(tabNumber, forKey: .tabNumber)
    }
    
}

extension Test {
    
    func testFieldsAsArray() -> ([TestField]) {
        return self.testFields?.array as! [TestField]
    }
   


Tests have one or more TestFields:

import Foundation
import CoreData

@objc(TestField)

public class TestField: NSManagedObject, Identifiable, Encodable {
    
    @NSManaged public var allowEmptyResponse: Bool
    @NSManaged public var label: String?
    @NSManaged public var maxValue: Double
    @NSManaged public var minValue: Double
    @NSManaged public var numDecimalPlaces: Int16
    @NSManaged public var testFieldId: String?
    @NSManaged public var testFieldResult: String?
    @NSManaged public var unitOfMeasurement: String?
    @NSManaged public var userUpdated: Bool
    @NSManaged public var test: Test?
    
    enum CodingKeys: String, CodingKey {
        case allowEmptyResponse
        case label
        case minValue
        case maxValue
        case numDecimalPlaces
        case testFieldId
        case testFieldResult
        case unitOfMeasurement
        case test
    }



TestView has a list of TestFieldViews:

import Foundation
import SwiftUI

struct TestView: View {
    @ObservedObject var test: Test
    
    var body: some View {
        ForEach(test.testFields, id: \.testFieldId) { field in
            TestFieldView(field: field) { newValue in
            }
        }
    }
}



Here's the TestFieldView:

import Foundation
import SwiftUI

struct TestFieldView: View {
    @ObservedObject var field: TestField
    
    @State private var value = ""
    
    @Environment(\.managedObjectContext) var managedObjectContext
    
    var body: some View {
        HStack {
            Text(field.label ?? "")
            Spacer()
            TextField(fieldRange(), text: $value, onEditingChanged: { changed in
                print("Edit Changed!")
                self.field.testFieldResult = self.value
                do {
                    try self.managedObjectContext.save()
                } catch {
                    print("cannot save!")
                }
            }, onCommit: {
                print("Commit!")
            })
        }
            .frame(width: 100)
            .keyboardType(UIKeyboardType.decimalPad)
    }


Thanks for any help or words of wisdom that might get me un-stuck! 🙂