Звоните веб-сервисы по alamofire соответственно - PullRequest
0 голосов
/ 22 января 2019

Я создаю приложение, которое должно вызывать некоторые веб-службы в начале приложения.
Я написал WebServiceManager, который содержит методы для вызова веб-служб и возвращает результат в 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.

Как я могу вызвать эти веб-службы, чтобы затем принять решение на основе значений UserDefaults?

1 Ответ

0 голосов
/ 23 января 2019

Методы 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 и сделать что-то вродеthis:

Замените ваши методы 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)
}
...