iOS Swift 如何检测登录错误原因以向用户显示正确的错误警报

iOS Swift how detect login error reason to show proper error alert to the user

我需要为我的应用程序创建登录功能,API 在成功登录的情况下检索身份验证令牌。 在我当前的实现中,网络层执行 API 调用并返回一个带有布尔值(取决于登录结果)和字符串令牌(我在请求登录的 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
             }
          }

你应该像这样使用完成:

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

如果你得到了数据completion(success: token, failure: nil)

如果出现错误,completion(success: nil, failure: error)

你也应该为错误添加完成块,因为错误也可能发生。

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

//your code here

}

如果您不想为成功和失败指定单独的完成,请参考 Davydov Denis 的回答。如果成功则错误将为零,反之亦然。

Also specify your Base URL in a seperate constant file and add only /login for easy understanding and clean code.