Swift Array.append в init () не работает в сочетании с Firestore (Google Cloud / FIrebase) - PullRequest
0 голосов
/ 24 апреля 2020

Я попробовал свой первый проект SwiftUI. Я только хочу показать некоторые данные, хранящиеся в Firestore (Google Firebase). Вот мой код:

import SwiftUI
import FirebaseFirestore
import FirebaseFirestoreSwift

struct MonsterObj: Identifiable, Equatable, Hashable {
    var id = UUID()
    var name: String
    var element: String
    var immune: String
    var size: String
    var twoStarWeakness: String
    var threeStarWeakness: String

    #if DEBUG
    static let exampleMonster = MonsterObj(id: UUID(), name: "Test Monster", element: "Test Element", immun: "Test immun", groesse: "Test groesse", twoStarWeakness: "Test 2 Weakness", threeStarWeakness: "Test3 Weakness")

    #endif

}

class MonsterC: ObservableObject {

    @Published var monsters = [MonsterObj]()

    init() {
        let db = Firestore.firestore()
        var monsterNames: [String] = []

        db.collection("Monster").getDocuments() { (querySnapshot, err) in
            if let err = err {
                print(err)
            } else {
                for document in querySnapshot!.documents {
                    monsterNames.append("\(document.documentID)")
                    print("document: \(document.documentID)")

                }
            }
        }

            for monsterName in monsterNames {
                print(monsterName)
                db.collection("Monster").document(monsterName).getDocument { (document, error) in
                    if let document = document, document.exists {
                        let elementGetter = document.get("element") as! String
                        let immuneGetter = document.get("immune") as! String
                        let sizeGetter = document.get("size") as! String
                        let twoStarWeaknessGetter = document.get("2 star weakness") as! String
                        let threeStarWeaknessGetter = document.get("3 star weakness")as! String

                        self.monsters.append(MonsterObj(name: monsterName, element: elementGetter, immune: immuneGetter, size: sizeGetter, twoStarWeakness: twoStarWeaknessGetter, threeStarWeakness: threeStarWeaknessGetter))

                        }
                }
            }
     }
}

Это мой вид:

import SwiftUI  

struct ContentView: View {  
    @EnvironmentObject var monsterT: MonsterC  

    var body: some View {  
        List(monsterT.monsters, id: \.self) { monster in  
            Text(monster.name)  
        }  
    }  
} 

И я сделал следующее для SceneDelegate.swift:

var window: UIWindow?  
var monsterT = MonsterC()  
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions {


    // Create the SwiftUI view that provides the window contents.  
    let contentView = ContentView().environmentObject(monsterT)  


    if let windowScene = scene as? UIWindowScene {  
        let window = UIWindow(windowScene: windowScene)  
        window.rootViewController = UIHostingController(rootView: contentView)  
        self.window = window  
        window.makeKeyAndVisible()  
    }  
}

Итак, моя проблема список пуст. В init класса Monster C я выяснил, что строка monsterNames.append("\document.documentID)") ничего не добавляет к monsterNames. Но print("document: \(document.documentID)") печатает все monsterNames.

Моя структура Google Firestore выглядит следующим образом:

    Collection -> Document -> Fields
-------------------------------------------
    Monster -> Anjanath -> immune: fire,
                           element: fire

et c. Есть только одна коллекция («Монстр»).

Может кто-нибудь объяснить новичку, почему .append здесь не работает, а печать делает все правильно?

1 Ответ

0 голосов
/ 25 апреля 2020

Вы должны понимать вызов асинхронных функций. Мой совет - реструктурировать ваш код, не рекомендуется делать эти асин c вызовы в вашем init ().

Ваша функция "db.collection (" Monster "). GetDocuments () {(querySnapshot, err) in ..." является асинхронной. Вы должны либо дождаться окончания использования результатов, либо сделать то, что вам нужно внутри функции. Обратите внимание, что у вас также есть другая функция asyn c "db.collection (" Monster "). Document (monsterName) .getDocument {"

*. Таким образом, .append не работает, потому что результаты вашей функции "db.collection ("Monster"). GetDocuments () {(querySnapshot, err) in ... "недоступны при выполнении .append.

Так что, если вы должны использовать этот хитрый код, попробуйте это исправить проблема с массивом:

class MonsterC: ObservableObject {

@Published var monsters = [MonsterObj]()

init() {
    let db = Firestore.firestore()

    db.collection("Monster").getDocuments() { (querySnapshot, err) in
        if let err = err {
            print(err)
        } else {
            var monsterNames: [String] = []
            for document in querySnapshot!.documents {
                monsterNames.append("\(document.documentID)")
                print("document: \(document.documentID)")

            }

            for monsterName in monsterNames {
                print(monsterName)
                db.collection("Monster").document(monsterName).getDocument { (document, error) in
                    if let document = document, document.exists {
                        let elementGetter = document.get("element") as! String
                        let immuneGetter = document.get("immune") as! String
                        let sizeGetter = document.get("size") as! String
                        let twoStarWeaknessGetter = document.get("2 star weakness") as! String
                        let threeStarWeaknessGetter = document.get("3 star weakness")as! String

                        self.monsters.append(MonsterObj(name: monsterName, element: elementGetter, immune: immuneGetter, size: sizeGetter, twoStarWeakness: twoStarWeaknessGetter, threeStarWeakness: threeStarWeaknessGetter))

                    }
                }
            }

        }
    }
}
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...