I am working on an app modeled after Paul's UltimatePortfolio. In the file AddRecipeView, I want to create a new recipe, with all its subordinate attributes and ingredients. This file/struct is called from ContentView.swift just as in UltimatePortfolio, as:
import SwiftUI
struct ContentView: View {
@SceneStorage("selectedView") var selectedView: String?
var body: some View {
TabView(selection: $selectedView) {
AddRecipeView()
.tag(AddRecipeView.tag)
.tabItem {
Image(systemName: "tray.and.arrow.down")
Text("Add Recipe")
}
}
}
}
My Recipe and Ingredient classes are defined in Main.xcdatamodeld, with Recipe having an attribute of name, of type String. I have stripped out all the additional code for Recipe attributes and Ingredient and its attributes.
There is a an extension on Recipe for name, in the file Recipe-CoreDataHelpers.swift, as:
extension Recipe {
var recipeName: String {
name ?? "" // runtime error here!
}
}
I get a compile error in AddRecipeView: ‘Cannot find “recipe” in scope’ on the line “addIngredient(to: recipe)“, when the line 'let recipe = Recipe()' is the first line of init(). And, if I move the line 'let recipe = Recipe()' above init(), I get a runtime error on the line 'name ?? "" ' in Recipe-CoreDataHelpers.swift. Apparently, something is wrong with 'recipe', but I can't figure out what. Can you please help with whatever I am missing?
TIA,
Bill
import SwiftUI
struct AddRecipeView: View {
@Environment(\.managedObjectContext) var managedObjectContext
@EnvironmentObject var dataController: DataController
@Environment(\.presentationMode) var presentationMode
@State private var name: String
static let tag: String? = "AddRecipeView"
init() {
let recipe = Recipe()
_name = State(wrappedValue: recipe.recipeName)
}
var body: some View {
Form {
Section(header: Text(“Basic settings”)) {
TextField(“Recipe Name”, text: $name.onChange(update))
}
Button {
addIngredient(to: recipe) // compile error here!
} label: {
Label(“Add New Ingredient”, systemImage: “plus”)
}
}
.navigationTitle(“Add Ingredient”)
.onDisappear(perform: dataController.save)
}
func addIngredient(to recipe: Recipe) {
withAnimation {
let ingredient = Ingredient(context: managedObjectContext)
ingredient.recipe = recipe
dataController.save()
}
}
func update() {
recipe.name = name
}
func delete() {
presentationMode.wrappedValue.dismiss()
}
}