我在从swift到firebase的查询中遇到问题。 bellow是我在firebase中的样本JSON:
Lulibvi-D220
Contas
-KwlPQZTqVfNhHAsFyW5
Nome: "Assets"
Numero: "1"
-KwlGJLUTqVfnhYHAsFyW5
Nome: "Liabilities"
Numero: "2"
我的代码如下:
let nome: String = "Liabilities"
let numero: String = "2"
ref = Database.database().reference()
ref.child("Contas").child("Assets").observeSingleEvent(of: .value) { (snapshot) in
let numero = (snapshot.value as? NSDictionary)?["Numero"] as? String
print (numero as Any)
}
调试时,调试器只是在(快照)之后跳转所有代码而不执行它。
我做错了什么?
感谢
答案 0 :(得分:1)
tl; dr:要在XCode中调试异步代码,请在完成处理程序内的第一个语句上放置一个断点。
更长的解释:
当您观察Firebase中的值时,可能需要任何时间来获取该数据。为防止您的程序在此期间被阻止,在您的代码继续运行时,数据将在后台从Firebase数据库加载。然后,当数据可用时,Firebase会调用您的完成处理程序。
这种模式称为异步加载,几乎适用于任何现代Web API。但是,习惯这可能非常困难。
查看发生的情况的一种简单方法是使用一些正确的日志记录语句来运行代码:
ref = Database.database().reference()
print("Before attaching observer")
ref.child("Contas").child("Assets").observeSingleEvent(of: .value) { (snapshot) in
print("Inside completion handler")
}
print("After attaching observer")
此代码将立即打印:
在加入观察者之前
附上观察员后
过了一会儿(取决于网络速度和其他因素):
内部完成处理程序
虽然有一些方法可以在块等待数据后生成代码(有关详细信息,请参阅下面的一些链接),处理异步加载的更常见方法是重新构建问题。而不是尝试编码“首先获取数据,然后打印它”,而不是将问题构建为“我们开始获取数据。每当我们获取数据时,我们就会打印它”。
将此模型编写为代码的方法是将需要访问Firebase 数据的所有代码移动到观察者的完成处理程序中。您的代码已经通过print (numero as Any)
在那里完成了。
要在XCode中调试异步代码,请在完成处理程序内的代码上放置一个断点。当数据从Firebase返回时,该断点将被点击。
还有一些问题也涉及这种行为: