我们当前正在制作一个iOS应用,并将Firebase作为其数据库。请在下面找到我们的代码。
static func getTilesPerRow () -> Int{
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
return -2
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
var num = -1
let queue = DispatchQueue(label: "observer")
userRef.child("tilesPerRow").observe(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
num = snapshot.value as? Int ?? 0
print("just updated the number to ", num)
print("the snapshot is ", snapshot)
print("the value is ", value)
print("the real value is", snapshot.value)
print("just making sure, the number that was set is ", num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
}
print("about to return from the function ", num)
return num
}
当前,在运行此代码时,我们得到以下输出。
about to return from the function -1
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
我们的预期输出是:
now inside the observe thing------------------
just updated the number to 5
the snapshot is Snap (tilesPerRow) 5
the value is nil
the real value is Optional(5)
just making sure, the number that was set is 5
about to return from the function 5
这里的问题是我们试图获取查询找到的值,但是由于.observe()是异步的,因此该函数在.observe()更新num的值之前完成。我们如何返回正确的值?
答案 0 :(得分:2)
你没有。
要获取异步操作结果,请使用块。
static func getTilesPerRow (@escaping completion: (Int?)->Void ) {
let user = Auth.auth().currentUser
guard let uid = user?.uid else {
completion(nil)
}
var ref: DatabaseReference!
ref = Database.database().reference()
let userRef = ref.child("user").child(uid)
userRef.child("tilesPerRow").observeSingleEvent(DataEventType.value, with: { (snapshot) in
// Get user value
print("now inside the observe thing------------------")
let value = snapshot.value as? NSDictionary
let num = snapshot.value as? Int ?? 0
completion(num)
}) { (error) in
print("there was an error!!!!!!!!!!!!!!!!!")
print(error.localizedDescription)
completion(nil)
}
}
准备好结果后,您将通过该块得到通知。成功后,您会得到实际要寻找的num
或发生任何错误时都会得到nil
。
即使您可以通过在completion
块的参数列表中添加额外的参数来区分发生哪种错误。
您还可以使用协议,但是那需要更多的知识,例如,此代码驻留在哪个类中,谁是此类事情的调用者。将协议目标设置为调用方,完成后,被调用方法将根据错误或成功案例触发不同的协议方法。
快乐的编码。