简体   繁体   English

信号量永远等待

[英]Semaphore waits forever

I'm trying to create a function that will execute a post request to an API and I want the function to wait before it returns but it does not seem to work properly.我正在尝试创建一个函数,该函数将执行对 API 的发布请求,我希望该函数在返回之前等待,但它似乎无法正常工作。 I'm not sure what I'm missing.我不确定我错过了什么。

As per the suggestion of another answer here on SO I'm using semaphores to accomplish this however it seems that it will "wait forever" since the app just hangs.根据 SO 上另一个答案的建议,我正在使用信号量来完成此操作,但是由于应用程序挂起,它似乎会“永远等待”。 I know the request is executed successfully and the app gets a response(tried with with prints all over the place).我知道请求已成功执行并且应用程序得到响应(尝试在整个地方打印)。

This is what I've done so far:这是我到目前为止所做的:

    func sendAuthRequest(username: String, password: String) -> Int {
        
        let sem = DispatchSemaphore(value: 0)
        var authStatus: Int = 0        
        
        let params = ["username":username, "password":password] as Dictionary<String, String>
        
        var request = URLRequest(url: URL(string: Constants.api_base_url + "/auth/validateuser")!)
        request.httpMethod = "POST"
        request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        
        
        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
           
            if let httpResponse = response as? HTTPURLResponse {
                print(httpResponse.statusCode)

                if (httpResponse.statusCode == 200) {
                    authStatus = 200
                } else if (httpResponse.statusCode == 403) {
                    authStatus = 403
                } else {
                    authStatus = 500
                }
            }

        })
        
        task.resume()
        sem.wait()
        return authStatus        
    }

Thanks!谢谢!

If I restructure it quickly, I would do it this way:如果我快速重组它,我会这样做:

func sendAuthRequest(username: String, password: String, completion: @escaping (Result<Int, Error>) -> Void) {
    let params = ["username":username, "password":password] as Dictionary<String, String>
    var request = URLRequest(url: URL(string: Constants.api_base_url + "/auth/validateuser")!)
    request.httpMethod = "POST"
    request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")
    let session = URLSession.shared
    let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
        if let error = error {
            completion(.failure(error))
            return
        }
        if let httpResponse = response as? HTTPURLResponse {
            var authStatus: Int
            print(httpResponse.statusCode)
            if (httpResponse.statusCode == 200) {
                authStatus = 200
            } else if (httpResponse.statusCode == 403) {
                authStatus = 403
            } else {
                authStatus = 500
            }
            completion(.success(authStatus))
        } else {
            let error = NSError(domain:"", code: 0, userInfo:[NSLocalizedDescriptionKey: "Failed to get response"])
            completion(.failure(error))
        }
    })
    task.resume()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM