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