我正在尝试从 Firebase 获取数据并将其作为一个对象添加到 Swift 数组中,但每当我运行该应用程序时,该数组都会打印出空的。当我在 observe 中放置一个 print
语句时,每个钱包都按我想要的方式打印出来,但钱包永远不会附加到数组中。
var purses = [Purse]()
override func viewDidLoad() {
fetchPurse(completion: {print(self.purses.count)})
}
func fetchPurse(completion: @escaping () -> ()){
let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/")
let user = (FIRAuth.auth()?.currentUser?.uid)!
let userRef = ref.child("users").child(user).child("devices")
userRef.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]{
let purse = Purse()
purse.setValuesForKeys(dictionary)
self.purses.append(purse)
completion()
}
}, withCancel: nil)
}
最佳答案
这听起来像是对异步方法工作原理的误解。
如果你使用这样的代码:
//at this point purses is empty..
fetchPurse()
print("purses count = \(purses.count)")
您将始终看到一个空的钱包数组。
问题在于 fetchPurse()
函数使用了异步的 Firebase 函数 observe
。它要求 Firebase 在添加新条目时运行您作为 with:
闭包传递的代码。 observe
函数立即返回,并在 FireBase 添加新子对象时调用您传递给它的闭包。
因此,您的 fetchPurse()
函数也会在新钱包对象添加到您的钱包数组之前返回。
正如@DávidPásztor 在他的评论中所说,您应该重构 fetchPurse 以获取一个在 purses 数组更新时调用的完成处理程序:
func fetchPurse(completion: () -> ){
let ref = FIRDatabase.database().reference(fromURL: "https://test-database-ba3a2.firebaseio.com/")
let user = (FIRAuth.auth()?.currentUser?.uid)!
let userRef = ref.child("users").child(user).child("devices")
userRef.observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]{
let purse = Purse()
purse.setValuesForKeys(dictionary)
self.purses.append(purse)
//This is the new line that calls your new completion handler
completion()
}
}, withCancel: nil)
}
然后你会这样调用它:
fetchPurse(completion: {
print("purses count = \(purses.count)")
}
关于ios - 使用 Firebase 字典在 Swift 中填充数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44681080/