简体   繁体   English

如何将环境 Object 传递给我的 ViewModel SwiftUI

[英]How do I pass in an Environment Object to my ViewModel SwiftUI

I am using a function to get recipes from a database via an API endpoint.我正在使用 function 通过 API 端点从数据库中获取食谱。 It takes in 3 parameters, fat, carbs, protein and I want these values to be equal to my environment object (or a calculation of two environment objects) fatGoal - fatProgress etc. However in my viewModel I get the following error when trying to use my environment object:它接受 3 个参数,脂肪、碳水化合物、蛋白质,我希望这些值等于我的环境 object(或两个环境对象的计算)fatGoal - fatProgress 等。但是在我的 viewModel 中,尝试使用时出现以下错误我的环境 object:

Thread 1: Fatal error: No ObservableObject of type UserInfoModel found. A View.environmentObject(_:) for UserInfoModel may be missing as an ancestor of this view.

This is my ViewModel service file:这是我的 ViewModel 服务文件:

import SwiftUI
import Combine
import Foundation

class MealViewModel: ObservableObject {
    
    @Published var nutrients: [RecipieAPI] = []
    
    @EnvironmentObject var person: UserInfoModel
    
    
    @State public var fat = 0
    @State public var carbs = 0
    @State public var protein = 0


    
    init() {
        
        fetchNutrients()


    }
    
    func fetchNutrients() {
        NetworkServices.fetchNutrients(maxProtein: self.person.recipeNutrientsSearch.protein , maxFat: self.person.recipeNutrientsSearch.fat,  maxCarbs: self.person.recipeNutrientsSearch.carb, number: 4) { (nutrients, error) in
            if let error = error {
                print(error)
            } else {
                if let nutrientList = nutrients as? [RecipieAPI] {
                    self.nutrients = nutrientList
                }
            }
        }
    }
}

The error is called in错误被调用

NetworkServices.fetchNutrients(maxProtein: self.person.recipeNutrientsSearch.protein , maxFat: self.person.recipeNutrientsSearch.fat,  maxCarbs: self.person.recipeNutrientsSearch.carb, number: 4) { (nutrients, error) in

Any help would be greatly appreciated任何帮助将不胜感激

Edit Content View:编辑内容视图:

import SwiftUI

struct ContentView: View {

    
    //Instantiating an object of UserInfo Model (referenced in App.swift too 
    @EnvironmentObject var person: UserInfoModel
    

    
    init() {
        //Setting appearance of UI colour
        UITabBar.appearance().backgroundColor = ColourManager.UIColour1
    }
    
    var body: some View {
        
        
        TabView {
            ProfileView().tabItem ({
                Text("Profile")
            }).tag(0)
            
            TrackerView().tabItem ({
                Text("Tracker")
            }
            ).tag(1)

            
            AddView().tabItem ({
                Text("Add")
            }).tag(2)
            
            MealView().tabItem ({
                Text("Meals")
            }).tag(3)
        }.accentColor(ColourManager.Colour3)
        .environmentObject(UserInfoModel())

        
        }

    }

Environment Object class: UserinfoModel:环境 Object class:用户信息型号:

import Foundation

class UserInfoModel: ObservableObject {
    
    
    struct UserInfo: Identifiable {
        var id = UUID()
        var firstName: String
        var height: Double
        var weight: Double
        var gender: String
        var age: Double
        var activityLevel: String
        var BMR: Double
        
    }
    
    struct AddedFoods:Identifiable{
        var name: String = ""
        var totalCals: Double = 0
        var totalProtein: Double = 0
        var totalCarbs: Double = 0
        var totalFat: Double = 0
        var id = UUID().uuidString
       //Your other properties
    }
    
    struct DailyCalorieGoals: Identifiable{
        var id = UUID()
        var calorieGoal: Double
        var fatGoal: Double
        var proteinGoal: Double
        var carbGoal: Double

    }
    
    struct CurrentCalorieProgress: Identifiable{
        var id = UUID()
        var calorieProgress: Double
        var fatProgress: Double
        var carbProgress: Double
        var proteinProgress: Double

    }
    
    struct SearchRecipeCalories: Identifiable{
        var id = UUID()
        var fat: Int
        var carb: Int
        var protein: Int

    }
    
    @Published var personUserInfo = UserInfo.init(firstName: "",  height: 0, weight: 0, gender: "", age: 0, activityLevel: "", BMR: 0)
    @Published var personDailyCalorieGoals = DailyCalorieGoals.init(calorieGoal: 2400, fatGoal: 40, proteinGoal: 40, carbGoal: 40)
    @Published var personCurrentCalorieProgress = CurrentCalorieProgress.init(calorieProgress: 1200, fatProgress:   12, carbProgress: 5, proteinProgress: 30)
    
    @Published var  recipeNutrientsSearch = SearchRecipeCalories.init(fat: 0, carb: 0, protein: 0)
    
    
}

EnvironmentObjects must be supplied by anscestor views! EnvironmentObjects 必须由祖先视图提供!


 import SwiftUI
    
    @main
    struct pro2App: App {    // <<: Here: your app name!
        var body: some Scene {
            WindowGroup {
                ContentView()
                    .environmentObject(MealViewModel()) // <<: Here!
                    .environmentObject(UserInfoModel.shared) // <<: Here!
            }
        }

}

    class MealViewModel: ObservableObject {
    
    @Published var nutrients: [RecipieAPI] = []
    
    let person: UserInfoModel.shared   // <<: Here
    
    
    @State public var fat = 0
    @State public var carbs = 0
    @State public var protein = 0


    
    init() {
        
        fetchNutrients()


    }
    
    func fetchNutrients() {
        NetworkServices.fetchNutrients(maxProtein: self.person.recipeNutrientsSearch.protein , maxFat: self.person.recipeNutrientsSearch.fat,  maxCarbs: self.person.recipeNutrientsSearch.carb, number: 4) { (nutrients, error) in
            if let error = error {
                print(error)
            } else {
                if let nutrientList = nutrients as? [RecipieAPI] {
                    self.nutrients = nutrientList
                }
            }
        }
    }
}

class UserInfoModel: ObservableObject {
    
static let shared: UserInfoModel = UserInfoModel() // <<: Here
    
    struct UserInfo: Identifiable {
        var id = UUID()
        var firstName: String
        var height: Double
        var weight: Double
        var gender: String
        var age: Double
        var activityLevel: String
        var BMR: Double
        
    }
    
    struct AddedFoods:Identifiable{
        var name: String = ""
        var totalCals: Double = 0
        var totalProtein: Double = 0
        var totalCarbs: Double = 0
        var totalFat: Double = 0
        var id = UUID().uuidString
       //Your other properties
    }
    
    struct DailyCalorieGoals: Identifiable{
        var id = UUID()
        var calorieGoal: Double
        var fatGoal: Double
        var proteinGoal: Double
        var carbGoal: Double

    }
    
    struct CurrentCalorieProgress: Identifiable{
        var id = UUID()
        var calorieProgress: Double
        var fatProgress: Double
        var carbProgress: Double
        var proteinProgress: Double

    }
    
    struct SearchRecipeCalories: Identifiable{
        var id = UUID()
        var fat: Int
        var carb: Int
        var protein: Int

    }
    
    @Published var personUserInfo = UserInfo.init(firstName: "",  height: 0, weight: 0, gender: "", age: 0, activityLevel: "", BMR: 0)
    @Published var personDailyCalorieGoals = DailyCalorieGoals.init(calorieGoal: 2400, fatGoal: 40, proteinGoal: 40, carbGoal: 40)
    @Published var personCurrentCalorieProgress = CurrentCalorieProgress.init(calorieProgress: 1200, fatProgress:   12, carbProgress: 5, proteinProgress: 30)
    
    @Published var  recipeNutrientsSearch = SearchRecipeCalories.init(fat: 0, carb: 0, protein: 0)
    
    
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM