【发布时间】:2017-03-30 04:17:15
【问题描述】:
我有一些连接到 firebase 的代码,当它到达代码的某个部分时,它会运行两次它也不会删除我的 waitAlertController 它导致我的代码崩溃,因为它运行了两次然后第二次没有值,因为它第一次运行时将其删除,这是我的代码
这是我添加等待视图控制器并启动完成方法的表格视图。
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let alertController = UIAlertController(title: "Accept Bet", message: "Match the bet of " + amountBets[indexPath.row], preferredStyle: .alert)
let okButton = UIAlertAction(title: "No", style: .default, handler: { (action) -> Void in
print("Ok button tapped")
})
let yesButton = UIAlertAction(title: "Yes", style: .default, handler: { (action) -> Void in
// let them know to wait a second or the bet won't go through
var waitController = UIAlertController(title: "Please Wait", message: "Your bet is being processed", preferredStyle: .alert)
self.present(waitController, animated: true, completion: nil)
//take away the usersMoney
self.takeAwayMoney(self.amountBets[indexPath.row],index: indexPath.row, completion: { (result: Bool?) in
guard let boolResult = result else {
return
}
var getResult = ""
print("You have taken away the users money")
print("you made it this far almost there")
//let delayInSeconds = 3.0 // 1
//DispatchQueue.main.asyncAfter(deadline: .now() + delayInSeconds) { // 2
})
if (self.userHasMoney == true) {
self.updateBet(indexPath.row, completion: { (result: Bool?) in
guard let checkRes = result else {
return
}
})
self.getOpoosingUserNames(self.userName, indexPath.row, completion: { (anothaResult: Bool?) in
guard let value = anothaResult else {
return print("didn't work")
}
//wait for the first view to load in case it uploads to fast
sleep(1)
self.dismiss(animated: true, completion: nil)
let successController = UIAlertController(title: "Success", message: "You have made a bet with " + self.opposingUserNames!, preferredStyle: .alert)
let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
successController.addAction(okButt)
self.present(successController, animated: true, completion: nil)
//lastly delete the opposing UserName
self.amountBets.remove(at: indexPath.row)
self.tableView.reloadData()
print("Second")
})
} else {
//display a alert that lets the user know hes broke
let brokeController = UIAlertController(title: "Failed", message: "Reason: You don't have enough money!", preferredStyle: .alert)
let okButt = UIAlertAction(title: "Ok", style: .default, handler: nil)
brokeController.addAction(okButt)
self.present(brokeController, animated: true, completion: nil)
}
return
})
alertController.addAction(okButton)
alertController.addAction(yesButton)
present(alertController, animated: true, completion: nil)
}
这是我的 takeMoneyAway 方法
func takeAwayMoney(_ howMuch: String, index: Int, completion: @escaping (Bool)-> ()) -> Void{
if let notMuch = Int(howMuch) {
let userID = FIRAuth.auth()?.currentUser?.uid
datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let money = value?["money"] as? String ?? ""
//convert money to int
if let conMoney = Int(money) {
var conMoreMoney = conMoney
if conMoreMoney < notMuch {
print(" You don't have enough money")
completion(false)
return
} else {
conMoreMoney -= notMuch
let values = ["money": String(conMoreMoney)]
//update the users money
self.datRef.child("User").child(userID!).updateChildValues(values)
completion(true)
/*
self.updateBet(index, completion: { (result: Bool?) in
guard let checkResult = result else {
return print("Failed to get result")
}
if checkResult == true {
completion(true)
} else {
completion(false)
}
})
*/
}
}
// ...
}) { (error) in
print(error.localizedDescription)
}
}
}
我的最后一个方法是去我的数据库更新值并抓住他们下注的人。
func updateBet(_ index: Int, completion: @escaping (_ something: Bool?) -> Void) {
let userID = FIRAuth.auth()?.currentUser?.uid
datRef.child("User").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
// ...
self.datRef.child("Bets").observe(.childAdded, with: { snapshot in
//
// this is the unique identifier of the bet. eg, -Kfx81GvUxoHpmmMwJ9P
guard let dict = snapshot.value as? [String: AnyHashable] else {
print("failed to get dictionary from Bets.\(self.userName)")
return
}
let values = ["OpposingUsername": self.userName,"Show": "no"]
self.datRef.child("Bets").child(self.tieBetToUser[index]).updateChildValues(values)
let checkTheCodeWentHere = "Success"
// now get the opposing username which is just the Username registered to that specific bet
self.datRef.child("Bets").child(self.tieBetToUser[index]).observeSingleEvent(of: .value, with: { snapshot in
let thisValue = snapshot.value as? NSDictionary
if let username = thisValue?["Username"] as? String {
self.opposingUserNames = username
completion(true)
} else {
completion(false)
}
})
})
}) { (error) in
print(error.localizedDescription)
}
}
所以在 tableview 方法中有一段代码说 if checkRes == true {} 花括号中的所有代码都运行了两次我用断点检查了这个,有人能告诉我这是为什么吗?
【问题讨论】:
-
您能否发布单个会话中的控制台日志,显示您的
print语句的输出? -
它将显示所有打印语句大约 20 次,每个 @Fahim 我更新了我的 xcode 中的代码,现在它可以工作了。我猜你不能嵌套完成函数
-
哦,我在断点测试过,我不记得了,但我很确定它不是。我现在无法弄清楚的一件事是,如果其中一个完成函数返回 false,我需要发生一些不同的事情。例如,我的第一个功能从用户那里拿走了钱。因此,如果用户没有钱,则该函数将返回 false,但函数仍将在其下方运行。我什至尝试设置一个布尔值,然后检查该布尔值是否为假,如果是则不要运行其他完成块@Fahim
-
通常,如果闭包中的动作有两个不同的结果,最简单的方法是传递两个闭包 - 一个代表成功,一个代表失败。然后根据闭包中发生的情况,调用成功块或失败块。
-
标签: ios swift firebase firebase-realtime-database completionhandler