sendSynchronousRequest Swift 3

Am de migrat o aplicație din Swift 2.3 în Swift 3 pe un Deployment Target 10, adică aduc aplicația astfel încât ea sa folosească avantajele IOS 10+.
Aplicația pe care o upgradez folosește la un moment dat următoarea funcție de verificare în mod sincron a conectivității la server:


private func isServerReachable_Swift2() -> Bool {

        var Status:Bool = false

        let url = NSURL(string: "URL dorit")

        let request = NSMutableURLRequest(url: url! as URL)

        request.httpMethod = "POST"

        request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData

        request.timeoutInterval = 10.0

        request.allowsCellularAccess = true

        var response: URLResponse?

        _ = (try? NSURLConnection.sendSynchronousRequest(request as URLRequest, returning: &response)) as NSData?

        if let httpResponse = response as? HTTPURLResponse {

            if httpResponse.statusCode == 200 {

                Status = true

                Log.d("server reachable")

            }

        }

        return Status;

    }

Ceea ce este depreciat în IOS 9+ este tocmai folosirea acestui sendSynchronousRequest(_:returning:). Corectă ar fi fost și folosirea unui try-catch pentru sendSynchronousRequest sub forma:

do {
    let data = try NSURLConnection.sendSynchronousRequest(request as URLRequest, returning: &response)
} catch (let e) {
    print(e)
}

Chiar dacă această problemă legată de synchronous este destul de delicată, SWIFT oferă întotdeauna o cale de a rezolva o astfel de problemă printr-un asynchronous pattern, adică prin adăugarea unui completion handler funcției mele.

Însă am preferat să explorez partea de Semaphores din SWIFT care mă va ajuta să realizez un request synchronous și să astept răspunsul de la server.

   private func isServerReachable() -> Bool {
        var status:Bool = false
        let dispatchSemaphore = DispatchSemaphore(value: 0)

        let url = NSURL(string: "URL dorit")
        let request = NSMutableURLRequest(url: url! as URL)
        request.httpMethod = "POST"
        request.cachePolicy = NSURLRequest.CachePolicy.reloadIgnoringLocalAndRemoteCacheData
        request.timeoutInterval = 10.0
        request.allowsCellularAccess = true
        
        let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error -> Void in
            if let httpResponse = response as? HTTPURLResponse {
                if httpResponse.statusCode == 200 {
                    status = true
                    dispatchSemaphore.signal()
                    Log.d("server reachable")
                }
            }
            
        })
        task.resume()
        // blochez thread-ul pana cand apare signal pe dispatchSemaphore
        dispatchSemaphore.wait()
        
        Log.d("Response in main thread status = \(status)")
        return status;
    }
Share Button