ios - Swift iOS - 如果对 Firebase 的网络调用时间过长,如何使用计时器关闭事件指示器

标签 ios swift asynchronous firebase grand-central-dispatch

当我将数据发送到 Firebase 时,有时必须使用嵌套完成 block 数据发送到不同的节点

实际代码如下,但这里有一个示例

buttonPressed{
    activityIndicator.startAnimating()
    levelTwoRef //send levelTwo data run 1st callback
         scoreRef  //send score data run 2nd callback
            powerRef //send power data run 3rd  callback
               lifeRef //send life data run Last callback for dispatch_async...
                  dispatch_async(dispatch_get_main_queue()){
                     activityIndicator.stopAnimating()
                     performSegueWithIdentifier....
                  }

按下按钮后,我会显示一个activityIndi​​cator。大多数时候一切正常,但我看到在 scoreRefPowerRef 周围的调用失败,这将是第一个和第二个回调。问题是我不会删除 activityIndi​​cator 直到最后一个 completion block 运行,因此 activityIndi​​cator 无限期地旋转(它永远不会到达那里) 。当旋转器旋转时,我还会阻止该 View 的用户界面,因此用户无能为力。

一些人建议我在通话中放置一个计时器,如果在 X 时间范围内没有完成,我会显示一个取消按钮来停止操作。 我不知道如何添加计时器。对于取消按钮,我只需使用 alertController 来停止一切

我有 2 个问题:

  1. 如何向调用添加计时器以及在什么时候使用它?我这么说是因为有时它会完成,有时它会完成 在不同的 block 上失败。
  2. 我如何确定所有事情应该完成的时间?我这么说是因为它通常需要几秒钟 成功完成,但有时需要长达 45 秒的时间。 如果网络拥塞,调用可能不会失败,只是 等待。

我仍在使用 Swift 2.2,因为我引用的书籍都是用它编写的。

代码:

class LevelOneCompletedController: UIViewController{

@IBOutlet weak var completedLevelButton: UIButton!

var ref: FIRDatabaseReference!
let uid = FIRAuth.auth()?.currentUser?.uid
let activityIndicator = UIActivityIndicatorView()

var levelDict = [String:AnyObject]()
var scoreDict = [String:AnyObject]()
var powerDict = [String:AnyObject]()
var lifeDict = [String:AnyObject]()


override func viewDidLoad() {
     super.viewDidLoad()
     self.ref = FIRDatabase.database().reference().child(self.uid!)
}


@IBAction func completedLevelButtonTapped(sender: UIButton){
     self.completedLevelButton.enabled = false
     self.activityIndicator.center = self.view.center
     self.activityIndicator.hidesWhenStopped = true
     self.activityIndicator.activityIndicatorViewStyle = .WhiteLarge
     self.view.addSubview(self.activityIndicator)
     self.activityIndicator.startAnimating()
     UIApplication.sharedApplication().beginIgnoringInteractionEvents()
     self.boardPassed()
}


fun boardPassed(){

   let levelTwoRef = self.ref.child("levelTwo").childByAutoID()
   levelTwoRef?.updateChildValues(self.levelDict, withCompletionBlock: {
            (error, ref) in 
            if error != nil{....}

     let scoreRef = self.ref.child("Score").childByAutoID()
     scoreRef?updateChildValues(self.scoreDict, withCompletionBlock: {
            (error, ref) in 
            if error != nil{....}

       let powerRef = self.ref.child("Power").childByAutoID()
       powerRef?updateChildValues(self.powerDict, withCompletionBlock: {
            (error, ref) in 
            if error != nil{....}

         let lifeRef = self.ref.child("Life").childByAutoID()
         lifeRef?updateChildValues(self.lifeDict, withCompletionBlock: {
            (error, ref) in 
            if error != nil{....}

            dispatch_async(dispatch_get_main_queue()){
               self.activityIndicator.stopAnimating()
               self.performSegueWithIdentifier("levelTwoSeque", sender: self)
               self.completedLevelButton.enabled = true
                UIApplication.sharedApplication().endIgnoringInteractionEvents()
            }
         }
       }
     }
   }
 }

}

最佳答案

没有计时器的解决方案是跟踪连接状态。您可以通过以下方式监听状态:

let connectedRef = FIRDatabase.database().reference(withPath: ".info/connected")
connectedRef.observe(.value, with: { snapshot in
  if snapshot.value as? Bool ?? false {
    print("Connected")
  } else {
    print("Not connected")
  }
})

您可以将更新的状态保存在变量中,并在每次请求之前检查它,然后根据需要启动/停止 activityIndi​​cator

更多信息可以在这里找到:Detecting Connection State .

关于ios - Swift iOS - 如果对 Firebase 的网络调用时间过长,如何使用计时器关闭事件指示器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42869068/

相关文章:

php - 使用PHP(和Symfony)的无状态和异步Web服务器

javascript - 在数组中加载大量条目会导致网页卡住

ios - Xcode Swift UI 侧边菜单内容未对齐

ios - 使用 Reachability 检查 Internet 连接不起作用

swift - 如何缩短关闭时间?

Swift:ARKit 基于 2 个节点放置一个矩形

C# - 在 for 循环中使用相同列表大小的索引位于数组边界之外

ios - 自定义 View TextField 如何计算TextField总和

ios - CIFilter 应用于图像不起作用 - swift

ios - 如何在 SpriteKit 中为 physicsWorld 设置 contactDelegate?