【问题标题】:Initialize variables with firebase data on SwiftUI app在 SwiftUI 应用程序上使用 firebase 数据初始化变量
【发布时间】:2020-04-09 21:24:58
【问题描述】:

这是我第一次使用 Swift/SwiftUI 进行编程,过去几周我一直遇到一个问题。

应用程序 我正在尝试构建一个应用程序,用户在其中输入游戏数据,这些数据存储在他们的手机上,一旦答案在 firebase 数据库中可用,它将与他们进行比较并计算分数。

到目前为止,我已经能够: - 将 Firebase 集成到 iOS 应用程序中 - 我已经能够对从数据库收集的信息运行列表/foreach 循环

目前我的问题如下: 我正在尝试从 firebase 加载信息,然后使用此信息与用户数据进行比较并计算分数。当我这样做时,从 firebase 返回数据的函数返回一个空数组。

Firebase 结果函数

func getResults() {
        ref.child("eventResults").observe(DataEventType.value) { (snapshot) in
            self.eventResults = []
            for child in snapshot.children {
                if let snapshot = child as? DataSnapshot,
                    let event = EventResults(snapshot: snapshot) {
                    self.eventResults.append(event)
                }
            }
        }
    }

如果我在没有计算的情况下在 SwiftUI 视图中运行该代码,它会正确提取并显示数据,这是一个正常工作的示例视图

import SwiftUI

struct TestView: View {
    @ObservedObject var session = FirebaseSession()


    var body: some View {

        ZStack {
            Color.init(red: 221/255, green: 221/255, blue: 221/255)
                .edgesIgnoringSafeArea(.all)
            VStack {
                List{
                    //
                    ForEach(self.session.eventResults) { event in

                        HStack() {
                            Text(event.name)
                                .font(.system(size: 30))
                            Spacer()
                            Text("\(event.answer)")
                                .font(.system(size: 30))

                        }

                    }

                }.frame(width: UIScreen.main.bounds.width*0.9)
            }.onAppear() {
                self.getFirebaseData()
            }
        }
    }

    func getFirebaseData() {
        session.getResults()
    }
}

但在另一个视图中,我试图在后台计算用户分数,以便用正确的分数更新用户配置文件,我尝试了多种方法来做到这一点,但初始数组总是空的。

下面是我尝试运行的示例代码


import SwiftUI
import CoreData

struct EventList : View {

    @Environment(\.managedObjectContext) var managedObjectContext
    @ObservedObject var session = FirebaseSession()

    @FetchRequest(entity: UserEvents.entity(),
                  sortDescriptors: [])

    var userEvents: FetchedResults<UserEvents>

    var body: some View {

        ZStack {
            Color.init(red: 221/255, green: 221/255, blue: 221/255)
                .edgesIgnoringSafeArea(.all)
            VStack {
                ScrollView {
                    VStack(alignment: .leading) {
                        ForEach(userEvents) { eventVar in
                                EventCard(eventVar: eventVar)
                                    .cornerRadius(0)
                                    .shadow(color: .black, radius: 5, x: 2, y: 2.0)
                                    .padding(.horizontal)
                                    .frame(width: UIScreen.main.bounds.width)
                        }
                    }
                }
            }
        }.onAppear{
            self.getFirebaseData()
            var testvar2 = self.session.eventResults // is empty
            self.calcScores(resultlist: self.session.eventResults)
        }
    }

    //MARK: calculate Scores

    func getFirebaseData() {
        session.getResults()
    }



    func calcScores(resultlist: [EventResults]) {
          var testcount = resultlist.count // is empty

        }
}

非常感谢任何帮助或指导, 丹尼尔

【问题讨论】:

    标签: swift firebase firebase-realtime-database swiftui


    【解决方案1】:

    根据 workingdog 的输入,我能够通过函数调用的微小变化使代码正常工作

    获取结果函数

    func getResults(completion: @escaping (_ message: String) -> Void) {
        ref.child("eventResults").observe(DataEventType.value) { (snapshot) in
            self.eventResults = []
            for child in snapshot.children {
                if let snapshot = child as? DataSnapshot,
                    let event = EventResults(snapshot: snapshot) {
                    self.eventResults.append(event)
                }
            }
           completion("DONE")
        }
    }
    

    但我不得不将函数调用修改为以下内容:

           session.getResults(completion: { message in
                   print(message)
    // code execution here
            })
    

    感谢大家的帮助!

    【讨论】:

      【解决方案2】:

      我看到的问题是在 EventList(以及其他任何地方)中调用 self.getFirebaseData() 调用 getResults() 并且这是一个异步调用。 您必须等到它完成才能拥有:

      var testvar2 = self.session.eventResults
      

      【讨论】:

        【解决方案3】:

        要解决您的问题,您可以尝试以下方法:

        func getResults(completion: @escaping () -> Void) {
            ref.child("eventResults").observe(DataEventType.value) { (snapshot) in
                self.eventResults = []
                for child in snapshot.children {
                    if let snapshot = child as? DataSnapshot,
                        let event = EventResults(snapshot: snapshot) {
                        self.eventResults.append(event)
                    }
                }
               completion()
            }
        }
        

        然后这样称呼它:

        session.getResults() {
            // now do something with eventResults
        }
        

        【讨论】:

        • 谢谢!我要试试这个,看看它是否能解决我的问题,会回来回答。
        • 所以这部分工作。该函数现在返回一个值并让我将其用于计算,但它只存储数组/字典的第一个值。
        • 我在发布后不久就意识到completion() 调用不在正确的位置。无论如何,我很高兴你让它工作。
        猜你喜欢
        • 1970-01-01
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 2018-12-30
        • 1970-01-01
        • 1970-01-01
        • 2021-09-05
        • 1970-01-01
        相关资源
        最近更新 更多