如何构造代码来处理异步Firebase快照?

时间:2017-03-05 20:13:57

标签: ios swift asynchronous firebase firebase-realtime-database

我有一个我无法解决的问题。很多问题都在JS中,我不太了解它们。

我使用Firebase作为我的IOS应用和Swift的数据库。 以下是我的情况:

我有一个类文件,其中包含可以检索数据库中的值的函数。我在某些viewControllers中调用了这些函数。

这些函数检索到的值会立即用于这些viewControllers

我的问题是我的应用程序因类文件函数返回的nil值而崩溃。这是因为异步Firebase快照。

假定包含值的变量在赋值之前使用=>我的应用程序崩溃或打印值为零。

然后我的问题很简单:我如何构建代码以避免此问题?我已经尝试过完成,但这对我不起作用:函数仍然是异步的。

以下是我在类文件中的一个功能:

func initAverageMark(completionHandler: @escaping (_ mark: Double) -> ()) {

    let userRef = ref.child("users").child((user?.uid)!).child("mark")

    userRef.observeSingleEvent(of: .value, with: { (snapshot) -> Void in
        if let mark: Double = snapshot.value as? Double {
            completionHandler(mark)
        }
    }) { (error) in
        print(error.localizedDescription)
    }
}

我的一个viewController代码:

private var totalAsks: Double!

override func viewDidLoad() {
    super.viewDidLoad()

    initInfos()
}

func initInfos() {
    mainUser().initTotalAsks{ total in
        self.totalAsks = total
}
    initLabels()
}

func initLabels() {
    totalAsksLabel.text = " \(totalAsks!)" // it crashs here
}

1 个答案:

答案 0 :(得分:0)

假设您想在viewController中将某些标签或某些内容设置为mark的值,您可以这样做。

mainUser().initTotalAsks { mark in
    self.totalAsksLabel.text = " \(mark)"
}

修改

或者,如果你绝对想要使用那双。

private var totalAsks: Double? = nil {
    didSet {
        initLabels()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    initInfos()
}

func initInfos() {
    mainUser().initTotalAsks{ total in
        self.totalAsks = total
    }
}

func initLabels() {
     guard totalAsks != nil else {
         return
     }
     totalAsksLabel.text = " \(totalAsks!)"
}