分别通过alamofire调用网络服务

时间:2019-01-22 20:45:00

标签: ios swift web-services alamofire

我正在创建一个应用程序,该应用程序应以该应用程序的开头调用某些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值做出决定?

1 个答案:

答案 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)
}