Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/99.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用DispatchQueue在回调中调用时不显示警报_Ios_Swift - Fatal编程技术网

Ios 使用DispatchQueue在回调中调用时不显示警报

Ios 使用DispatchQueue在回调中调用时不显示警报,ios,swift,Ios,Swift,我试图在调用某个API时收到错误时显示警报 首先,我尝试在不使用DispatchQueue.main的情况下调用警报,但随后出现了一个错误,我无法从后台进程调用它 我的代码现在如下所示: func activate(code: String, callback: () -> Void, errorCallback: @escaping () -> Void) -> Void { let semaphore = DispatchSemaphore (value:

我试图在调用某个API时收到错误时显示警报

首先,我尝试在不使用DispatchQueue.main的情况下调用警报,但随后出现了一个错误,我无法从后台进程调用它

我的代码现在如下所示:

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)
        }
    }
}