Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

ios - Swift 3 - Send make synchronous http request

I have the following code:

func completeLoadAction(urlString:String) -> Int {
    let url = URL(string:urlString.trimmingCharacters(in: .whitespaces))
    let request = URLRequest(url: url!)
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {                                                 // check for fundamental networking error
            print("error=(error)")
            let ac = UIAlertController(title: "Unable to complete", message: "The load has been added to the completion queue. This will be processed once there is a connection.", preferredStyle: .alert)
            ac.addAction(UIAlertAction(title: "OK", style: .default))
            self.present(ac, animated:  true)
            return
        }

    let httpStatus = response as? HTTPURLResponse
        var httpStatusCode:Int = (httpStatus?.statusCode)!

        let responseString = String(data: data, encoding: .utf8)
        print("responseString = (responseString)")
        let ac = UIAlertController(title: "Completed Successfully", message: "The "+coldel+" has been completed successfully", preferredStyle: .alert)
        ac.addAction(UIAlertAction(title:"Continue", style: .default, handler:  { action in self.performSegue(withIdentifier: "segueConfirmedLoad", sender: self) }))

        self.present(ac, animated: true)

    }
    task.resume()
    return httpStatusCode
}

I need to be able to call this and at the same time check the return value as it is the http status code, it will let me know if the call was successful or not.

Problem is because it's in a dataTask I can't access the responses status code here

var httpStatusCode:Int = (httpStatus?.statusCode)!

Because the task doesn't start until Task.Resume() is called and the task is asynchronous so it will never work.

Are there any ways around this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

To make it synchronous and wait you can use semaphores such as below

struct Login {

    static func execute() -> Bool {
        let request = NSURLRequest....

        var success = false
        let semaphore = DispatchSemaphore(value: 0)
        let task = URLSession.shared.dataTask(with: request, completionHandler: { _, response, error in
            if let error = error {
                print("Error while trying to re-authenticate the user: (error)")
            } else if let response = response as? HTTPURLResponse,
                300..<600 ~= response.statusCode {
                    print("Error while trying to re-authenticate the user, statusCode: (response.statusCode)")
            } else {
                success = true
            }
            semaphore.signal()
        }) 

        task.resume()
        _ = semaphore.wait(timeout: DispatchTime.distantFuture)
        return success
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...