ios - 您如何创建一个必须对 firebase 数据库进行查询并将查询值作为 int 返回的函数?
问题描述
我们目前正在制作一个 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 的值之前完成。我们如何返回正确的值?
解决方案
你没有。
要获得异步操作结果,请使用块。
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
即使您可以通过在块中的参数列表中添加额外的参数来区分发生了什么样的错误。
你也可以使用协议,但这需要更多的知识,比如这段代码在哪个类中,谁是这类事情的调用者。将协议目标设置为调用者,完成后被调用的方法将根据发生的错误或成功情况触发不同的协议方法。
快乐编码。
推荐阅读
- python - 如何使用 Elbow 方法获得自组织地图“SOM”的最佳 K?
- arrays - GCC 11 在不使用字符串操作时给出 -Wstringop-overflow
- sql - how to pass a list into postgres as a parameter
- docker - 带有子域的反向代理 nginx docker 容器
- flutter - 有人知道如何在条形码中存储许多值吗?
- swift - 使用 CAKeyframeAnimation 在 Scenekit 中为旋转节点设置动画
- c++ - 如何将 shared_ptr 变量推回 C++ 中的 shared_ptr 向量?
- python - 具有副作用的 python 函数的类型提示(写入文件),并且没有返回值
- javascript - 为什么这个 React 函数返回 NaN?
- arrays - 尝试使用 ForEach 循环从 .exe 中获取产品版本,然后基于该版本执行一批函数