nickreps
nickreps

Reputation: 1080

Cannot convert value of type 'Published<[StepsEntity]>.Publisher' to expected argument type 'Binding<String>'

StepsEntity is a core data entity

Receiving the following error when attempting to display a string value in a TextField: "Cannot convert value of type 'Published<[StepsEntity]>.Publisher' to expected argument type 'Binding'"

I know this is because StepsEntity in my core data model is @Published. @Published works great here as it allows all the data to be updated neatly. How can I display an @Published in a TextField?

Below is the piece where I am receiving the error:

List {
            VStack(alignment: .center) {
                if let recipeSteps = (vm.recipes[vm.getRecordsCount() - 1].steps?.allObjects as? [StepsEntity])?.sorted { $0.stepNumber < $1.stepNumber } {
                    
                    if (textFieldCount == 1) {
                        //do nothing
                    } else if (textFieldCount > 1) {
                        ForEach(recipeSteps, id: \.stepNumber) { index in
                            HStack {
                               
                                Text(String(index.stepNumber) + ".").bold()
                                TextField("", text: vm.$recipeSteps) //This is where the error is seen
                                
                            }
                        }.onDelete(perform: { index in
                            self.vm.deleteRecipeSteps(at: index, from: vm.recipes[vm.getRecordsCount() - 1])
                            })
                    }
                
                }
            }

vm.recipeSteps refers to my CoreDataRelationshipViewModel, which is where all core data functions are handled. this is declared in the view struct as:

@StateObject var vm = CoreDataRelationshipViewModel()

Here is a snippet from the CoreDataRelationshipViewModel class:

class CoreDataRelationshipViewModel: ObservableObject {

let manager = CoreDataManager.instance
@Published var recipes: [RecipeEntity] = []
@Published var recipeSteps: [StepsEntity] = []

init() {
    getRecipes()
}

func getRecipes() { ////more functions for retrieving, deleting, etc. in this section

I have tried converting the Published var to a binding but no luck:

TextField("", text: Binding(vm.$recipeSteps)!)

I have also tried referencing the recipeSteps declared in the if let statement within the list, but that does not work either.

I have been at it for a few days, and I think I have exhausted all options. Open to all ideas here. Maybe I need to rebuild my model?

Thoughts?

--Edits--

Upper portion of struct, where variables are created:

struct AddItemView: View {

@StateObject var viewModel = ViewModel()
@State var frameDimensions: CGFloat = 0
@State var imageButtonText: String = "Click To Add Image"
@State var imageToUpload: Data

@StateObject var vm = CoreDataRelationshipViewModel()
@Environment(\.presentationMode) var presentationMode
@State var stepInfo: String = ""
@State var textFieldCount: Int = 1
@State var stepNumber: [Int]
@State var recordsCount = 1
@State var errorText = ""
@State var stepErrorColor = Color.white.opacity(0)
@State var nameErrorColor = Color.white.opacity(0)

var body: some View {
    ZStack {
        HStack {

Upvotes: 0

Views: 4446

Answers (2)

nickreps
nickreps

Reputation: 1080

I ended up restructuring the way my core data save works. Instead of saving item by item, I am now looping through a for in loop to save data all at the end. This allows me to display the data locally via some state variables, but then save the full array to my core data entity.

Upvotes: 0

Ben Myers
Ben Myers

Reputation: 1395

Your problem is that

TextField("", text: vm.$recipeSteps)

should actually be

TextField("", text: $vm.recipeSteps)

as you need to pass the view model with Binding rather than recipeSteps (which, when using $ to pass it beyond vm's dot accessor, passes a generic Publisher).

Also, this would only work if the @Published property in your view model conforms to StringProtocol (is a string). Are you sure recipeSteps is a string that can be edited via TextField?

Upvotes: 6

Related Questions