Попытка вызвать функцию внутри init()
. У меня есть функция, которая принимает параметр, который я вызываю в инициализаторе. Сначала я устанавливаю для параметра пустую строку, пока не передам значение в другом представлении, когда оно появится.
Моя проблема в том, что функция не обновляется сразу при первом появлении представления. Моя цель состоит в том, чтобы просто запустить функцию сразу после создания представления и немедленно обновить представление (где я отображаю в своем представлении значения из функции).
Я предполагаю, что, поскольку я передаю начальную пустую строку во время init(), моя функция не запускается с обновленной переменной. Я не хочу устанавливать для @State значение @Binding, поскольку я не хочу передавать значение каждый раз, когда я вызываю наблюдаемый объект. Любые советы высоко ценится.
Подводя итог моей проблеме, когда я вызываю рецепт grabItems при первом появлении моего представления, он изначально не вызывается с правильным параметром (он вызывается с пустой строкой).
class testClass: ObservableObject {
@State var uidNonUser: String
@Published var itemsNonUser = [Item]() // items saved
init(){
self.uidNonUser = ""
grabItems(userUID: uidNonUser) // << grabs things
}
}
struct testStruct: View {
@ObservedObject var rm = testClass()
@State var userUID: String // << variable passing to grabItems
var body: some View {
Text(rm.itemsNonUser.count)
.onAppear{
rm.grabItems(userUID: userUID)
}
}
}
К вашему сведению - вставка моего фактического рецепта GrabItems ниже в качестве справки на случай, если это поможет понять проблему.
func grabItems(userUID: String){
//grab user thats not current user
FirebaseManager.shared.firestore
.collection("users")
.document(userUID) // << passed in from view
.collection("userRecipes")
.addSnapshotListener { (snapshot, err) in
guard let documents = snapshot?.documents else{
print("no documents present")
return
}
self.itemsNonUser = documents.map { (querySnapshot) -> RecipeItem in
let data = querySnapshot.data()
let recipeTitle = data ["recipeTitle"] as? String ?? ""
let recipePrepTime = data ["recipePrepTime"] as? String ?? ""
let recipeImage = data ["recipeImage"] as? String ?? ""
let createdAt = data ["createdAt"] as? String ?? ""
let ingredients = data ["ingredientItem"] as? [String: String] ?? ["": ""]
let directions = data ["directions"] as? [String] ?? [""]
let recipeID = data ["recipeID"] as? String ?? ""
let recipeCaloriesMacro = data ["recipeCaloriesMacro"] as? Int ?? 0
let recipeFatMacro = data ["recipeFatMacro"] as? Int ?? 0
let recipeCarbMacro = data ["recipeCarbMacro"] as? Int ?? 0
let recipeProteinMacro = data ["recipeProteinMacro"] as? Int ?? 0
let recipe = RecipeItem(id: recipeID, recipeTitle:recipeTitle , recipePrepTime: recipePrepTime, recipeImage: recipeImage, createdAt: createdAt, recipeCaloriesMacro: recipeCaloriesMacro, recipeFatMacro: recipeFatMacro, recipeCarbMacro:recipeCarbMacro, recipeProteinMacro: recipeProteinMacro, directions: directions, ingredientItem: ingredients)
return recipe
}
}
}
в onAppear
вы пробовали звонить rm.grabItems(userUID: userUID)
вместо testClass.grabItems(userUID: userUID)
Попробуйте этот пример кода, чтобы обновить представление при его первом появлении.
// for testing
struct RecipeItem {
var recipeTitle: String
// ...
}
class TestClass: ObservableObject {
@Published var itemsNonUser = [RecipeItem]() // <-- here
func grabItems(userUID: String){
//...
// for testing
itemsNonUser = [RecipeItem(recipeTitle: "banana cake with ID: \(userUID)")]
}
}
struct TestStruct: View {
@StateObject var rm = TestClass() // <-- here
@State var userUID: String
var body: some View {
VStack {
Text(rm.itemsNonUser.first?.recipeTitle ?? "no name")
Text("count: \(rm.itemsNonUser.count)") // <-- here
}
.onAppear{
rm.grabItems(userUID: userUID) // <-- here
}
}
}
struct ContentView: View {
let userUID = "123456"
var body: some View {
TestStruct(userUID: userUID) // <-- here
}
}
Спасибо за ответ. Только почему-то это не работает. UserUID передается правильно, когда появляется представление. Сказав это, функция просто не работает, так как когда я вызываю itemsNonUser.count, она возвращает 0 (в этом примере должно быть 1)
Я предлагаю вам создать новый проект в Xcode 14.2, скопировать и вставить мой код точно так, как он есть, и запустить его на реальном устройстве (не в превью). Дайте нам знать, если это все еще не работает, поскольку мне интересно найти причину, по которой это не работает для кого-то другого.
Тоже работает, спасибо
В моем случае (и это могло быть специфично для моего конкретного случая) я обновил рецепт grabItems, чтобы он возвращал Int, так как мое представление пыталось отобразить количество.
Затем я просто вызвал его прямо в представление, вот так, и это сработало:
Text(String(rm.grabItems(userUID: userUID))).bold() // << calling function directly in view
Обратите внимание, не используйте
@State var uidNonUser: String
вclass testClass: ObservableObject
.@State
предназначен только для просмотра. Используйтеvar
или просто используйтеgrabItems(userUID: "")
в своемinit()
. Однако вашinit()
не требуется, насколько я вижу, он ничего не делает.