iOS Swift, как обнаружить причину ошибки входа в систему, чтобы показать правильное предупреждение об ошибке пользователю - PullRequest
1 голос
/ 03 июня 2019

Мне нужно создать функцию входа для моего приложения, API извлекает токен аутентификации в случае успешного входа.В моей текущей реализации сетевой уровень выполняет вызов API и передает обратно замыкание с логическим значением (в зависимости от результата входа в систему) и токеном String (который мне нужен в viewController, который запросил вход в систему).

Моя проблема в том, что я хотел бы показать надлежащее предупреждение пользователю в зависимости от причины сбоя при входе в систему (например, нет соединения, неверный пароль).С этой реализацией я вижу, что не могу достичь этого результата.Может ли кто-нибудь помочь мне улучшить мое решение?

Вот мой код:

    public func load(_ urlString: String, email: String, password: String, withCompletion completion: @escaping (_:Bool,_ token: String) -> Void) {

        let session = URLSession(configuration: .ephemeral, delegate: nil, delegateQueue: OperationQueue.main)
        let url = URL(string: urlString)!

        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "POST"
        let parameters: [String: Any] = [
        "email": email,
        "password": password
         ]
        do {
           urlRequest.httpBody = try JSONSerialization.data(withJSONObject: parameters, options: .prettyPrinted)
           } catch let error {
        }

        urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type")
        urlRequest.addValue("application/json", forHTTPHeaderField: "Accept")
        let task = session.dataTask(with: urlRequest, completionHandler: { (data: Data?, response: URLResponse?, error: Error?) -> Void in
            guard let data = data,
                let response = response as? HTTPURLResponse,
            error == nil else {                                              
                    return
        }

            guard (200 ... 299) ~= response.statusCode else {                    
            completion(false,"")
            return
        }

        let responseString = String(data: data, encoding: .utf8)
        do{

            let jsonResponse = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as? [String : Any]
            print(jsonResponse) //Response result

            let token: String = jsonResponse?["token"] as! String
            completion(true,token)
        } catch let parsingError {
            completion(false,"")
            return
        }
    })
    task.resume()
  }
}

Мой контроллер просмотра

        network.load(NetworkController.loginURL,email: email, password: password) { [weak self] (result :Bool, token: String) in
             if result{
                 print("Successful Authentication with token \(token)")
             }
             else{
                 print("Authentication failed")
                 //show Error alert
             }
          }

Ответы [ 2 ]

2 голосов
/ 03 июня 2019

Вы также должны добавить блок завершения для ошибки, так как ошибка также может произойти.

public func load(email: String, password: String, success: @escaping (token: String) -> (), failure: @escaping (Error) -> ()) {

//your code here

}

Если вы не хотите указывать отдельное завершение для успеха и неудачи, пожалуйста, обратитесь к ответу Давыдова Дениса.В случае успеха ошибка будет равна нулю, и наоборот.

Также укажите базовый URL в отдельном константном файле и добавьте только / login для простоты понимания и очистки кода.

0 голосов
/ 03 июня 2019

вы должны использовать завершение следующим образом:

completion: @escaping (success token: String?, failure error: Error?) -> Void)

если вы получили данные completion(success: token, failure: nil)

и если вы получили ошибку, completion(success: nil, failure: error)

...