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.
我需要为我的应用程序创建登录功能,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.