Ios Firebase完成下载后如何直接执行代码?
我有一些代码需要在Firebase完成下载任务后立即执行。问题是,此代码总是在下载完成之前运行Ios Firebase完成下载后如何直接执行代码?,ios,swift,firebase,firebase-realtime-database,Ios,Swift,Firebase,Firebase Realtime Database,我有一些代码需要在Firebase完成下载任务后立即执行。问题是,此代码总是在下载完成之前运行 if currentVersionNumber < newVersionNumber { print("Feed: button donwloading cards") //self.databaseButton.setTitle("Downloading New Cards...", for: .normal) ref.o
if currentVersionNumber < newVersionNumber {
print("Feed: button donwloading cards")
//self.databaseButton.setTitle("Downloading New Cards...", for: .normal)
ref.observe(.value, with: { snapshot in
print("Feed: Checking for new cards from firebase")
for item in snapshot.children {
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
cardRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Feed: error occured")
print(error)
} else {
// Data for "images/island.jpg" is returned
cards.imageName = data!
print("Feed: downloaded \(cards.name)")
}
}
// add to updated list of cards
updateCards.append(cards);
}
})
} else {
print("Feed: cards are up to date. \(currentVersionNumber)")
}
})
如果currentVersionNumberVoid in
如果(错误!=nil){
//哦,发生了一个错误!
打印(“提要:发生错误”)
打印(错误)
}否则{
//返回“images/island.jpg”的数据
cards.imageName=数据!
打印(“提要:下载\(cards.name)”)
}
}
//添加到更新的卡片列表中
updateCards.追加(卡片);
}
})
}否则{
打印(“提要:卡是最新的。\(currentVersionNumber)”)
}
})
这段代码从Firebase数据库下载我想要的项目,但在完成之前,它将运行其后的任何代码。我该如何做才能选择在下载完成后立即执行代码块?这是因为Firebase的所有更新都发生在后台线程中,而您的代码在主线程上执行。要处理此调用,请在函数中调用firebase方法,该函数具有一个闭包,在firebase下载完成后立即调用该闭包 例如: 在
视图中加载:
override func viewDidLoad() {
super.viewDidLoad()
fetchData {
//do whatever action you wish to perform on download completion
mainTableView.reloadData()
}
}
func fetchData(andOnCompletion completion:@escaping ()->()){
ref.observe(.value, with: { snapshot in
print("Feed: Checking for new cards from firebase")
for item in snapshot.children {
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
cardRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Feed: error occured")
print(error)
} else {
// Data for "images/island.jpg" is returned
cards.imageName = data!
print("Feed: downloaded \(cards.name)")
}
}
// add to updated list of cards
updateCards.append(cards);
}
//call the block when done processing
completion()
})
}
这是因为Firebase的所有更新都发生在后台线程中,并且您的代码在主线程上执行。要处理此调用,请在函数中调用firebase方法,该函数具有一个闭包,在firebase下载完成后立即调用该闭包
例如:
在视图中加载:
override func viewDidLoad() {
super.viewDidLoad()
fetchData {
//do whatever action you wish to perform on download completion
mainTableView.reloadData()
}
}
func fetchData(andOnCompletion completion:@escaping ()->()){
ref.observe(.value, with: { snapshot in
print("Feed: Checking for new cards from firebase")
for item in snapshot.children {
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
cardRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Feed: error occured")
print(error)
} else {
// Data for "images/island.jpg" is returned
cards.imageName = data!
print("Feed: downloaded \(cards.name)")
}
}
// add to updated list of cards
updateCards.append(cards);
}
//call the block when done processing
completion()
})
}
这些网络请求是异步运行的,因此在网络请求完成时,它们之后的任何代码都将继续运行
您应该将updateCards.append(卡片)移动到内部闭包中,以便在第二个闭包完成之前不会调用它,然后,如果您有其他代码需要在完成时运行,您可以将其移动到此函数中,或者使用带有完成处理程序的闭包,以确保在运行更多代码之前完成所有网络请求,这些代码依赖于响应
getCardData { [weak self] in
// do whatever you need to do after completion
}
func getCardData(_ completion: () -> ()) {
print("Feed: button donwloading cards")
//self.databaseButton.setTitle("Downloading New Cards...", for: .normal)
ref.observe(.value, with: { snapshot in
print("Feed: Checking for new cards from firebase")
for item in snapshot.children {
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
cardRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Feed: error occured")
print(error)
completion() // this is where you would normally throw an error or have a closure that accepts an optional error you would pass in to know it failed
} else {
// Data for "images/island.jpg" is returned
cards.imageName = data!
print("Feed: downloaded \(cards.name)")
updateCards.append(cards);
completion()// now you know all network requests are complete
}
}
}
})
}
这些网络请求是异步运行的,因此在网络请求完成时,它们之后的任何代码都将继续运行
您应该将updateCards.append(卡片)移动到内部闭包中,以便在第二个闭包完成之前不会调用它,然后,如果您有其他代码需要在完成时运行,您可以将其移动到此函数中,或者使用带有完成处理程序的闭包,以确保在运行更多代码之前完成所有网络请求,这些代码依赖于响应
getCardData { [weak self] in
// do whatever you need to do after completion
}
func getCardData(_ completion: () -> ()) {
print("Feed: button donwloading cards")
//self.databaseButton.setTitle("Downloading New Cards...", for: .normal)
ref.observe(.value, with: { snapshot in
print("Feed: Checking for new cards from firebase")
for item in snapshot.children {
// Download in memory with a maximum allowed size of 1MB (1 * 1024 * 1024 bytes)
cardRef.data(withMaxSize: 1 * 1024 * 1024) { (data, error) -> Void in
if (error != nil) {
// Uh-oh, an error occurred!
print("Feed: error occured")
print(error)
completion() // this is where you would normally throw an error or have a closure that accepts an optional error you would pass in to know it failed
} else {
// Data for "images/island.jpg" is returned
cards.imageName = data!
print("Feed: downloaded \(cards.name)")
updateCards.append(cards);
completion()// now you know all network requests are complete
}
}
}
})
}
通过在下载中添加if语句来解决我的问题,该语句检查附加到updateCards的卡数是否等于快照中的卡数。感谢两位回答这个问题的人,因为我也使用了completion()方法,很高兴我去了解这个我不知道存在的概念 通过在下载中添加一条if语句来解决我的问题,该语句检查updateCards中附加的卡数是否等于快照中的卡数。感谢两位回答这个问题的人,因为我也使用了completion()方法,很高兴我去了解这个我不知道存在的概念 我看到一个答案被添加,但我不知道他们会有多近。如果我不花点时间,我会删除它,但我想两个例子比一个好。只是提醒一下,你没有将updateCards.append移动到内部闭包。这似乎对我不起作用,因为它要求在完成下载之前完成。我看到添加了一个答案,但我不知道它们会有多接近。如果我不花点时间,我会删除它,但我想两个例子比一个好。只是提醒一下,你没有将updateCards.append移动到内部闭包。这似乎对我不起作用,因为它在下载完成之前调用完成。两个答案似乎都不起作用,在下载完成之前调用完成。另一个答案似乎起作用,在下载完成之前调用完成