Swift4で同期通信をする
今回は、Swift4で同期HTTP通信を実現します。
使いどきはあまりイメージできておりませんが、書き換えチャレンジです。
参考にしたSwift2のコード
まず、Swift4で同期HTTP通信をするためにこちらのサイトを参考にしました。
サイトに掲載されていたSwift2のコードも、勉強のため載せておきます。
public class HttpClientImpl {
private let session: NSURLSession
public init(config: NSURLSessionConfiguration? = nil) {
self.session = config.map { NSURLSession(configuration: $0) } ?? NSURLSession.sharedSession()
}
public func execute(request: NSURLRequest) -> (NSData?, NSURLResponse?, NSError?) {
var d: NSData? = nil
var r: NSURLResponse? = nil
var e: NSError? = nil
let semaphore = dispatch_semaphore_create(0)
session
.dataTaskWithRequest(request) { (data, response, error) -> Void in
d = data
r = response
e = error
dispatch_semaphore_signal(semaphore)
}
.resume()
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
return (d, r, e)
}
}
Swift2からSwift4へ変換する
この状態で、Compiler Errorが6つ出ていました。
基本的には、Fix
ボタンをクリックしていったら良いんですが、、dispatch_semaphore_wait
だけ、Fix
ボタンでは消えてくれませんでした。😭
この問題については、AppleのDeveloperページを参考にします。
ときどき、こういったFix
ボタンで変換できないのが面倒ですね。。
https://developer.apple.com/documentation/dispatch/dispatchsemaphore
結果、次のようになりました。
完成したコード
全て変換し終えたコードがこちらです。
public class HttpClientImpl {
private let session: URLSession
public init(config: URLSessionConfiguration? = nil) {
self.session = config.map { URLSession(configuration: $0) } ?? URLSession.shared
}
public func execute(request: URLRequest) -> (NSData?, URLResponse?, NSError?) {
var d: NSData? = nil
var r: URLResponse? = nil
var e: NSError? = nil
let semaphore = DispatchSemaphore(value: 0)
session
.dataTask(with: request) { (data, response, error) -> Void in
d = data as NSData?
r = response
e = error as NSError?
semaphore.signal()
}
.resume()
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
return (d, r, e)
}
}
また、使うときはこんな感じです。
// 通信先のURLを生成.
let myUrl:URL = URL(string: "https://www.example.com/xxx")!
let req = NSMutableURLRequest(url: myUrl)
let postText = "key1=value1&key2=value2"
let postData = postText.data(using: String.Encoding.utf8)
req.httpMethod = "POST"
req.httpBody = postData
let myHttpSession = HttpClientImpl()
let (data, _, _) = myHttpSession.execute(request: req as URLRequest)
if data != nil {
// 受け取ったデータに対する処理
}