ios - принудительно ждать ответа Alamofire, прежде чем вернуться в swift 4 - PullRequest
0 голосов
/ 28 ноября 2018

У меня возникла ситуация, когда мне пришлось проверять предоставленный номер мобильного телефона при регистрации и входе через OTP-код.У меня все настроено в моих Accounts вызовах, чтобы использовать их на SignUpViewController и SignInViewController.

В ViewControllers сначала я хочу отправить OTP, а затем проверить, отправлено ли оно с сервераответ на push VerificationViewController, я использую Alamofire для работы в сети и SwiftyJSON для анализа ответов JSON.Теперь давайте углубимся в суть моей проблемы:

Вот часть моего SignUpViewController класса

var acc: Accounts = Accounts()

@IBAction func signupAction(_ sender: Any) {
        if validateFields() {
            let fname = self.firstName.text!
            let lname = self.lastName.text!
            let pnum = self.phoneNumber.text!
            self.acc.setFirstName(fn: fname)
            self.acc.setLastName(ln: lname)
            self.acc.setPhoneNumber(pn: pnum)
            let result = self.acc.sendOTP()
            if (result) {
                let targetVC = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "signupVerfication") as? SignupVerficationViewController
                self.navigationController?.pushViewController(targetVC!, animated: true)
            }
            else {
                CustomComponents().alertWithTitle(title: "Error", message: "Unable to Verify Phone Number,Please Try again!", ViewController: self)
            }
        }
}

А вот часть моего Accounts класса

func sendOTP() -> Bool {
        let conf = APIConfig()
        var returnedResult = false
        conf.setURL(url: "patient/auth/send-totp")
        conf.setHeader(head: ["Content-Type": "Application/json"])
        conf.setBody(body: ["phone_number": self.phoneNumber])
        print(self.phoneNumber)
        Alamofire.request(conf.getURL(), method: .post, parameters: conf.getBody(), encoding: JSONEncoding.default, headers: conf.getHeader()).validate(statusCode: 200..<600).responseData { response in
            let status = response.response?.statusCode
            print(status!)
            let swiftJSONVar = JSON(response.result.value!)
            print(swiftJSONVar)
            if (status == 200) {
                returnedResult = true
            }
        }
        return returnedResult
    }

Я всегда получаю оповещение как выход при каждом запуске приложения, несмотря на то, что, как вы можете видеть, я отлаживал ответ, печатая его здесь print(status!) и здесь print(swiftJSONVar).Вывод распечатки - 200 в качестве кода состояния, и я получил оставшуюся часть моего ответа.

Я просматривал многие учебные пособия онлайн, такие как: Учебное пособие по Grand Central для рассылки Swift 4 и Безопасное кодирование с параллелизмом в Swift 4 и более, но не удалось реализовать GCD для моих блоков кода.

Мне нужна ваша помощь, пожалуйста?

1 Ответ

0 голосов
/ 28 ноября 2018

Метод sendOTP имеет тип возврата Bool, который немедленно возвращается, так как Alamofire запрос равен asynchronous, и вы устанавливаете значение falseResult false в верхней части, которое немедленно возвращается без ожидания ответа.После получения ответа от Alamofire значение returnResult устанавливается равным true, но нет способа сообщить об этом вызывающей стороне.Поскольку false возвращается из метода sendOTP, он показывает предупреждение об ошибке.

Используйте закрытие вместо возврата bool из sendOTP, который принимает Bool и возвращает void

func sendOTP(_ completion: @escaping (Bool) -> Void) {
    let conf = APIConfig()
    var returnedResult = false
    conf.setURL(url: "patient/auth/send-totp")
    conf.setHeader(head: ["Content-Type": "Application/json"])
    conf.setBody(body: ["phone_number": self.phoneNumber])
    print(self.phoneNumber)
    Alamofire.request(conf.getURL(), method: .post, parameters: conf.getBody(), encoding: JSONEncoding.default, headers: conf.getHeader()).validate(statusCode: 200..<600).responseData { response in
        let status = response.response?.statusCode
        print(status!)
        let swiftJSONVar = JSON(response.result.value!)
        print(swiftJSONVar)
        if (status == 200) {
            completion(true)
        } else {
            completion(false)
        }
    }
}

, теперь вы можете вызвать как

self.acc.sendOTP { (result) in
    if result {
        //show vc
        let targetVC = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "signupVerfication") as? SignupVerficationViewController
        self.navigationController?.pushViewController(targetVC!, animated: true)
    } else {
        //show error alert
        CustomComponents().alertWithTitle(title: "Error", message: "Unable to Verify Phone Number,Please Try again!", ViewController: self)
    }
}

Наряду с учебником GCD я бы порекомендовал учебники URLSession и Alamofire , а также чтобы понять, как работает сеть в iOS.

...