如何在 swift 5 中的完成块内向用户显示警报
How to show an alert to the user inside a completion block in swift 5
我有一个 API 调用网络服务器的应用程序。我终于让 API 调用正常工作,现在可以解析服务器 return 的 JSON 数据,但我仍然坚持尝试在请求失败时向用户显示警报.例如,我的服务器可以 return {"success": false, "error": "You didn't ask nicely"} 显然这个错误不是真实的,而是 return编辑。我只能检查 URLSession.shared.dataTask 的完成块内的错误,但是如果我尝试从内部显示一个警报,我会得到一个错误,即我无法从 UI 上的后台线程执行任何操作.
代码现在相当简单...
URLSession.shared.dataTask(with: self.request) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
//continue on with processing the response...
completion(.success(fullResponse))
}.resume()
然后在我的调用代码中我有...
connector.connect(pin) { (result) in
switch(result) {
case .success(let response):
if let response = response {
if response.success {
//do things
} else {
self.alert(title: "Error while connecting", message: response.error)
}
}
case .failure(let error):
self.alert(title: "Unable to connect", message: error)
}
}
这导致了我无法从后台线程对 ui 线程执行任何操作的错误。如果是这样,我如何让用户知道 API 调用失败了?我必须能够通知用户。谢谢。
您需要将其包装在 DispatchQueue.main.async
中,因为 URLSession.shared.dataTask
的回调发生在后台线程
DispatchQueue.main.async {
self.alert(title: "Error while connecting", message: response.error)
}
也一样
self.alert(title: "Unable to connect", message: error)
但最好将所有代码包装在 alert
主队列中的函数内,使其成为一个地方
您可以使用另一种方法,而不是在 connector.connect(pin)
的回调上调用 DispatchQueue.main.async
,您也可以在 [=15] 上调用 completion
块之前执行此操作=] 像这样。
URLSession.shared.dataTask(with: self.request) { (data, response, error) in
if let error = error {
DispatchQueue.main.async {
completion(.failure(error))
}
return
}
//continue on with processing the response...
DispatchQueue.main.async {
completion(.success(fullResponse))
}
}.resume()
通过这样做,您在 connector.connect(pin)
中的代码将不会被放置在厄运金字塔中,并且完成块中的所有内容都 运行 在主线程上。
connector.connect(pin) { result in
// everything in here is on the main thread now
}
我有一个 API 调用网络服务器的应用程序。我终于让 API 调用正常工作,现在可以解析服务器 return 的 JSON 数据,但我仍然坚持尝试在请求失败时向用户显示警报.例如,我的服务器可以 return {"success": false, "error": "You didn't ask nicely"} 显然这个错误不是真实的,而是 return编辑。我只能检查 URLSession.shared.dataTask 的完成块内的错误,但是如果我尝试从内部显示一个警报,我会得到一个错误,即我无法从 UI 上的后台线程执行任何操作.
代码现在相当简单...
URLSession.shared.dataTask(with: self.request) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
//continue on with processing the response...
completion(.success(fullResponse))
}.resume()
然后在我的调用代码中我有...
connector.connect(pin) { (result) in
switch(result) {
case .success(let response):
if let response = response {
if response.success {
//do things
} else {
self.alert(title: "Error while connecting", message: response.error)
}
}
case .failure(let error):
self.alert(title: "Unable to connect", message: error)
}
}
这导致了我无法从后台线程对 ui 线程执行任何操作的错误。如果是这样,我如何让用户知道 API 调用失败了?我必须能够通知用户。谢谢。
您需要将其包装在 DispatchQueue.main.async
中,因为 URLSession.shared.dataTask
的回调发生在后台线程
DispatchQueue.main.async {
self.alert(title: "Error while connecting", message: response.error)
}
也一样
self.alert(title: "Unable to connect", message: error)
但最好将所有代码包装在 alert
主队列中的函数内,使其成为一个地方
您可以使用另一种方法,而不是在 connector.connect(pin)
的回调上调用 DispatchQueue.main.async
,您也可以在 [=15] 上调用 completion
块之前执行此操作=] 像这样。
URLSession.shared.dataTask(with: self.request) { (data, response, error) in
if let error = error {
DispatchQueue.main.async {
completion(.failure(error))
}
return
}
//continue on with processing the response...
DispatchQueue.main.async {
completion(.success(fullResponse))
}
}.resume()
通过这样做,您在 connector.connect(pin)
中的代码将不会被放置在厄运金字塔中,并且完成块中的所有内容都 运行 在主线程上。
connector.connect(pin) { result in
// everything in here is on the main thread now
}