我正在创建一个应用程序,该应用程序应以该应用程序的开头调用某些Web服务。
我写了一个WebServiceManager
,其中包含用于调用Web服务并在completionHandler
中返回结果的方法,这是WebServiceManager
的一种方法:
extension WebServiceManager {
func checkVersion(completionHandler: @escaping (CheckVersionResponse?, Error?) -> ()) {
sessionManager?.adapter = BaseClientInterceptor()
let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
let buildNumber = Bundle.main.infoDictionary!["CFBundleVersion"] as! String
sessionManager?.request(Config.VERSION_URL + "/\(appVersion)/\(buildNumber)" + Config.STATUS, method: .get).responseData { response in
print(response.response?.statusCode)
switch response.result {
case .success(let value):
print("----WS: checkVersion Success-----")
let value = JSON(value)
print(value)
let response = CheckVersionResponse(responseCode: response.response?.statusCode ?? -1)
if (response.getResponseCode() == 200) {
response.setUrl(value["url"].string ?? "")
response.setNow(value["now"].intValue)
response.setStatus(value["status"].stringValue)
response.setMessage(value["message"].stringValue)
}
completionHandler(response, nil)
case .failure(let error):
print(error)
print("----WS: checkVersion Failed-----")
completionHandler(nil, error)
}
}
}
}
并且我在SplashScreenViewController
中使用了该管理器的一些方法:
class SplashViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
WebServiceManager.shared.checkVersion() { response, error in
//...
}
WebServiceManager.shared.getCurrentDate() { response, error in
//...
}
WebServiceManager.shared.getUpdatedKeyValues() { response, error in
//...
}
if !UserDefaults.standard.bool(forKey: "hasRegistered") {
self.performSegue(withIdentifier: "ToRegistration", sender: self)
} else {
self.performSegue(withIdentifier: "ToMain", sender: self)
}
}
}
我希望此方法逐行运行,但首先会通过if
。
如何依次调用这些Web服务,然后根据UserDefaults
值做出决定?
答案 0 :(得分:1)
sessionManager.request方法是异步的,因此它们将不会在viewDidAppear上(逐行)同步执行(以您丢失super.viewDidAppear()的方式)
如果您希望在这3个服务之后执行一些代码,则可以执行以下操作,不确定是否为最佳解决方案:
class SplashViewController: UIViewController {
private var allDone = 0
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
WebServiceManager.shared.checkVersion() { response, error in
//...
checkUserDefault()
}
WebServiceManager.shared.getCurrentDate() { response, error in
//...
checkUserDefault()
}
WebServiceManager.shared.getUpdatedKeyValues() { response, error in
//...
checkUserDefault()
}
}
private func checkUserDefault() {
allDone += 1
/// When all 3 services are finish
if allDone == 3 {
if !UserDefaults.standard.bool(forKey: "hasRegistered") {
self.performSegue(withIdentifier: "ToRegistration", sender: self)
} else {
self.performSegue(withIdentifier: "ToMain", sender: self)
}
}
}
}
希望对您有帮助!
编辑:这是基于现有代码的最简单解决方案,如果您想以“正确的方式”进行操作,则可能要检查“承诺”:http://khanlou.com/2016/08/promises-in-swift/ https://www.raywenderlich.com/9208-getting-started-with-promisekit
您需要使用PromiseKit并执行以下操作:
替换您的API方法,使它们使用Promise作为响应:
func checkVersion() -> Promise<CheckVersionResponse> {
sessionManager?.adapter = BaseClientInterceptor()
let appVersion = Bundle.main.infoDictionary!["CFBundleShortVersionString"] as! String
let buildNumber = Bundle.main.infoDictionary!["CFBundleVersion"] as! String
// Return a Promise for the caller of this function to use.
return Promise { fulfill, reject in
// Inside the Promise, make an HTTP request
sessionManager?.request(Config.VERSION_URL + "/\(appVersion)/\(buildNumber)" + Config.STATUS, method: .get).responseData { response in
print(response.response?.statusCode)
switch response.result {
case .success(let value):
print("----WS: checkVersion Success-----")
let value = JSON(value)
print(value)
let response = CheckVersionResponse(responseCode: response.response?.statusCode ?? -1)
if (response.getResponseCode() == 200) {
response.setUrl(value["url"].string ?? "")
response.setNow(value["now"].intValue)
response.setStatus(value["status"].stringValue)
response.setMessage(value["message"].stringValue)
}
fulfill(response)
case .failure(let error):
print(error)
print("----WS: checkVersion Failed-----")
reject(error)
}
}
}
}
然后在UIViewController上调用WebServiceManager方法,如下所示:
WebServiceManager.shared.checkVersion().then { response in
// ....
WebServiceManager.shared.getCurrentDate()
}.then { date in
// ...
WebServiceManager.shared.getUpdatedKeyValues()
}.catch { error in
print(error)
}