在swift中,我如何等到收到服务器响应后再继续?

在swift中,我如何等到收到服务器响应后再继续?,swift,server,segue,response,completion,Swift,Server,Segue,Response,Completion,如果我从服务器得到某个响应,我只想执行一个segue。在swift中,我如何才能等到收到响应才继续?底线是,您不需要“等待”响应,而只需指定响应到来时希望发生的事情。例如,如果您希望在完成某个网络请求时执行segue,则应采用完成处理程序模式 这里的问题是,您可能习惯于将UI控件挂接到Interface Builder中的segue。在本例中,我们不希望这样做,而是希望执行网络请求,然后让其完成处理程序以编程方式调用segue。因此,我们必须创建一个可以通过编程执行的segue,然后将您的按钮连

如果我从服务器得到某个响应,我只想执行一个segue。在swift中,我如何才能等到收到响应才继续?

底线是,您不需要“等待”响应,而只需指定响应到来时希望发生的事情。例如,如果您希望在完成某个网络请求时执行segue,则应采用完成处理程序模式

这里的问题是,您可能习惯于将UI控件挂接到Interface Builder中的segue。在本例中,我们不希望这样做,而是希望执行网络请求,然后让其完成处理程序以编程方式调用segue。因此,我们必须创建一个可以通过编程执行的segue,然后将您的按钮连接到执行网络请求的
@IBAction
,如果合适,还可以通过编程执行segue。但是,请注意,不应将segue直接连接到按钮。我们将以编程的方式来实现这一点

例如:

  • 通过控制从第一个场景上方栏中的视图控制器图标拖动到第二个场景,定义两个视图控制器之间的分段:

  • 通过选择segue并转到“属性检查器”选项卡,为该segue提供情节提要标识符:

  • 将按钮(或任何将触发此序列的东西)连接到
    @iAction

  • 编写一个执行网络请求的
    @IBAction
    ,并在完成后以编程方式调用该segue:

    @IBAction func didTapButton(_ sender: Any) {
        let request = URLRequest(...).       // prepare request however your app requires
    
        let waitingView = showWaitingView()  // present something so that the user knows some network request is in progress
    
        // perform network request
    
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            // regardless of how we exit this, now that request is done, let's 
            // make sure to remove visual indication that network request was underway
    
            defer {
                DispatchQueue.main.async {
                    waitingView.removeFromSuperview()
                }
            }
    
            // make sure there wasn't an error; you'll undoubtedly have additional
            // criteria to apply here, but this is a start
    
            guard let data = data, error == nil else {
                print(error ?? "Unknown error")
                return
            }
    
            // parse and process the response however is appropriate in your case, e.g., if JSON:
            //
            // guard let responseObject = try? JSONSerialization.jsonObject(with data) else {
            //     // handle parsing error here
            //     return
            // }
            //
            // // do whatever you want with the parsed JSON here
    
            // do something with response
    
            DispatchQueue.main.async {
                performSegue(withIdentifier: "SegueToSceneTwo", sender: self)
            }
        }
        task.resume()
    }
    
    /// Show some view so user knows network request is underway
    ///
    /// You can do whatever you want here, but I'll blur the view and add `UIActivityIndicatorView`.
    
    private func showWaitingView() -> UIView {
        let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Dark))
        effectView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(effectView)
        NSLayoutConstraint.activateConstraints([
            effectView.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor),
            effectView.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor),
            effectView.topAnchor.constraintEqualToAnchor(view.topAnchor),
            effectView.bottomAnchor.constraintEqualToAnchor(view.bottomAnchor)
        ])
    
        let spinner = UIActivityIndicatorView(activityIndicatorStyle: .WhiteLarge)
        effectView.addSubview(spinner)
        spinner.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activateConstraints([
            spinner.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor),
            spinner.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor)
        ])
        spinner.startAnimating()
    
        return effectView
    }
    

  • 使用completionHandler:您几乎不想主动等待,因为这会阻塞当前线程。屏幕截图和代码很好,但它们似乎与使用
    NSURLSession
    @TomHarrington没有任何关系步骤4是执行
    NSURLSessionTask
    。步骤1-3概述了以编程方式执行步骤4中的步骤所需的操作。如果我理解正确的话,OP是在询问如何在执行segue之前等待网络响应。好吧,我想我在所有关于如何设置segue的讨论中都迷失了方向。@TomHarrington-是的,我解释得不够清楚。只是当人们谈论让segue等待某个网络请求时,通常是两部分的问题,他们不熟悉异步模式,但也不习惯以编程方式执行segue。我试图添加一些文字来阐明我的观点。