简体   繁体   中英

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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