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