在 Swift 中向用户显示网络错误消息
Posted
技术标签:
【中文标题】在 Swift 中向用户显示网络错误消息【英文标题】:Displaying networking error message to user in Swift 【发布时间】:2020-08-18 11:53:54 【问题描述】:问题是如何使这段代码可重用,尤其是网络方法中的错误检查和完成处理程序中的条件,所以我没有重复的代码?
我创建了一个方法,该方法使用 URLSession 发出网络请求,并使用状态码作为参数调用完成处理程序。在完成处理中,我创建了一个显示错误消息或基于状态码执行 segue 的条件。所有这些代码都有效,但我想让它可重用,所以我没有重复的代码。
联网方式:
func saveMessage(data: String, day: String, completion: @escaping (Int)->())
let url = URL(string: "\(Constants.baseURL)/daily_mindset/today_message")
guard let requestUrl = url else fatalError()
var request = URLRequest(url: requestUrl)
request.httpMethod = "POST"
// Set HTTP Request Header
request.setValue("application/json", forHTTPHeaderField: "Accept")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let jsonData = encodeJSON(with: data, day: day)
request.httpBody = jsonData
let task = URLSession.shared.dataTask(with: request) (data, response, error) in
if error != nil
completion(700)
return
guard let response = response as? HTTPURLResponse else
completion(701)
return
guard (200...299).contains(response.statusCode) else
completion(response.statusCode)
return
guard let mime = response.mimeType, mime == "application/json" else
completion(702)
return
guard let data = data else
completion(703)
return
do
let todoItemModel = try JSONDecoder().decode(MessageData.self, from: data)
Constants.currentMindsetId = todoItemModel._id!
print("Response data:\n \(todoItemModel)")
catch let jsonErr
print(jsonErr)
completion(response.statusCode)
task.resume()
使用完成处理程序调用网络方法:
messageManager.saveMessage(data: textView.text, day: day, completion: (statusCode: Int) -> Void in
if (200...299).contains(statusCode)
DispatchQueue.main.async
self.performSegue(withIdentifier: "ToDailyMindsetScreen", sender: sender)
else if (400...499).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Please make sure you filled in the all the required fields."
else if (500...599).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Sorry, couldn't reach our server."
else if (700...).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Sorry, something went wrong. Try again later."
)
我想重用的网络方法中的代码:
if error != nil
completion(700)
return
guard let response = response as? HTTPURLResponse else
completion(701)
return
guard (200...299).contains(response.statusCode) else
completion(response.statusCode)
return
guard let mime = response.mimeType, mime == "application/json" else
completion(702)
return
guard let data = data else
completion(703)
return
我想重用的完成处理程序中的代码:
if (200...299).contains(statusCode)
DispatchQueue.main.async
self.performSegue(withIdentifier: "ToDailyMindsetScreen", sender: sender)
else if (400...499).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Please make sure you filled in the all the required fields."
else if (500...599).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Sorry, couldn't reach our server."
else if (700...).contains(statusCode)
DispatchQueue.main.async
self.errorLabel.text = "Sorry, something went wrong. Try again later."
【问题讨论】:
也许你应该把这个发到codereview.stackexchange.com 【参考方案1】:如果错误消息是特定于 ViewController 的,您可以从创建一个函数开始,该函数根据状态代码返回消息,如下所示:
private func getErrorMessageFor(statusCode: Int) -> String?
if (200...299).contains(statusCode)
//If no error message is returned assume that the request was a success
return nil
else if (400...499).contains(statusCode)
return "Please make sure you filled in the all the required fields."
else if (500...599).contains(statusCode)
return "Sorry, couldn't reach our server."
else if (700...).contains(statusCode)
return "Sorry, something went wrong. Try again later."
else
return "Message for other errors?"
您始终可以将此代码移至 ViewController 子类以提供更通用的错误消息,并在以后覆盖它以提供特定 View Controller 的更详细的错误。
class BaseViewController: UIViewController
func getErrorMessageFor(statusCode: Int) -> String?
//base implementation here
class OtherViewController: BaseViewController
override func getErrorMessageFor(statusCode: Int) -> String?
//create a new error message only for statusCode 404
if statusCode == 404
return "The requested resource was not found on the server. Please contact the support team"
else
return super.getErrorMessageFor(statusCode: statusCode)
请记住,随着应用程序的增长,您可能希望创建一个 APIClient 来为您处理网络和错误处理。看看https://bustoutsolutions.github.io/siesta/,很人性化
【讨论】:
以上是关于在 Swift 中向用户显示网络错误消息的主要内容,如果未能解决你的问题,请参考以下文章
这会导致崩溃..?或者我们也可以在 Swift 中向 nil 发送消息..?