LoginSignup
29
24

More than 5 years have passed since last update.

Swiftで同期HTTP通信を走らせる

Last updated at Posted at 2016-02-07

 NSURLSession を使って通信を走らせる場合、コールバックやデリゲートなどで後処理を指定する非同期通信となります。基本的に通信処理を非同期で扱うのは正しいと思います。しかし、コールバックやデリゲート、FutureObservable などのスタイルに縛られず処理を書きたいとなると、同期通信にしたくなります。

 そこで強制的に同期通信にしてしまうコードを書いてみました。これで晴れてコールバックを渡す必要も無く、デリゲートを指定する必要もない。そして FutureObservable に包む必要のない状態になりました。

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

}

 実際にUI層から呼び出す前に、適当なタイミングで Future なり Observable なりに lift すればよいので、同期である方が柔軟な設計が可能になるのではないかなと思います。execute の戻り型が、 Either<NSError, HttpResponse> とかになっているとさらに良さそうですね。

 純粋な HttpClientFutureObservable に依存する必然性がないので、このコードが安定したものであれば、使っていきたいと考えています。iOS開発に詳しい方、このコード実際どうなんですかね?(丸投げ)

29
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
24