Ios 使用DispatchQueue在回调中调用时不显示警报
我试图在调用某个API时收到错误时显示警报 首先,我尝试在不使用DispatchQueue.main的情况下调用警报,但随后出现了一个错误,我无法从后台进程调用它 我的代码现在如下所示:Ios 使用DispatchQueue在回调中调用时不显示警报,ios,swift,Ios,Swift,我试图在调用某个API时收到错误时显示警报 首先,我尝试在不使用DispatchQueue.main的情况下调用警报,但随后出现了一个错误,我无法从后台进程调用它 我的代码现在如下所示: func activate(code: String, callback: () -> Void, errorCallback: @escaping () -> Void) -> Void { let semaphore = DispatchSemaphore (value:
func activate(code: String, callback: () -> Void, errorCallback: @escaping () -> Void) -> Void {
let semaphore = DispatchSemaphore (value: 0)
let json: [String: String?] = ["phone_number": MySession.shared().get()?.phoneNumber, "code": code]
let postData = try? JSONSerialization.data(withJSONObject: json)
var request = URLRequest(url: URL(string: "\(API_URL)/users/activate")!, timeoutInterval: 10)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if error != nil {
DispatchQueue.main.async {
print("test error callback 1")
errorCallback()
}
return
}
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
DispatchQueue.main.async {
print("test error callback")
errorCallback()
}
return
}
let responseObject = try? JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any]
MySession.shared().set(object: responseObject ?? nil)
print(String(data: data!, encoding: .utf8)!)
semaphore.signal()
}
task.resume()
semaphore.wait()
callback()
}
这就是我所说的
AuthService.shared().activate(code: activationCode!, callback: {
let storyBoard: UIStoryboard = UIStoryboard(name: "Home", bundle: nil)
let homeViewController = storyBoard.instantiateViewController(withIdentifier: "HomeVC") as! HomeViewController
homeViewController.modalPresentationStyle = .fullScreen
self.present(homeViewController, animated: true, completion: nil)
}, errorCallback: {
self.alertError(errorTitle: "", errorText: NSLocalizedString("Wrong activation code", comment: "Signup"))
})
我正在检查日志,但看不到在DispatchQueue.main.async
下添加的日志
如果我在DispatchQueue.main.async上面添加一个日志,那么我可以看到该日志。但我无法显示警报。有什么建议吗?不幸的是,Postman没有生成非常好的模板代码 它尝试使用信号量将异步操作转换为同步操作。它还使用
try?
而不是正确的do/try/catch
,因此错误将被忽略而不是报告
您可以使用Result
类型来组合成功和错误回调
UI操作(如显示新视图或错误警报)应该在回调关闭中,而不是在网络操作本身中。处理操作返回的数据时也是如此:
func activate(code: String, callback: @escaping ((Result<[String:Any],Error>)->Void)) {
let json: [String: String?] = ["phone_number": MySession.shared().get()?.phoneNumber, "code": code]
let postData = try? JSONSerialization.data(withJSONObject: json)
var request = URLRequest(url: URL(string: "\(API_URL)/users/activate")!, timeoutInterval: 10)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
callback(.failure(error))
return
}
do {
if let responseObject = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] {
callback(.success(responseObject))
return
}
} catch {
callback(.failure(error))
}
}
task.resume()
}
进一步的改进是创建一个适当的结构,并将其与
Codable
一起使用,而不是使用字典。从会话任务闭包中调用callback
。不要使用信号量阻塞主线程并等待。这看起来像是邮递员生成的坏代码。有点好奇。为什么要在同一个函数中同时使用完成回调和返回?@Paulw11是的,这是一个邮递员生成的代码,我正在尝试调整它。回调
调用工作正常。errorCallback
和print(“测试错误回调”)
永远不会触发(DispatchQueue.main.async下的所有内容)@Paulw11如果我移动callback
以在会话任务关闭内调用,那么它不会打开我期望的VC。因此,它会遇到与errorClosure
相同的问题,其中没有显示警报。
AuthService.shared().activate(code: activationCode!) { result in
DispatchQueue.main.async {
switch result {
case .failure (let error):
self.alertError(errorTitle: "", errorText: NSLocalizedString("Wrong activation code \(error)", comment: "Signup"))
case .success (let result):
MySession.shared().set(object: result)
let storyBoard: UIStoryboard = UIStoryboard(name: "Home", bundle: nil)
let homeViewController = storyBoard.instantiateViewController(withIdentifier: "HomeVC") as! HomeViewController
homeViewController.modalPresentationStyle = .fullScreen
self.present(homeViewController, animated: true, completion: nil)
}
}
}