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