以前、NSURLSessionに関する記事を書いた。

[iOS] NSURLSessionを使って通信を行う

今回はSwiftで同じことをやってみる。
 
画像をダウンロードする
今回もここから始めていこう。
まずはStoryboardでこのように設定する。
nsurlsession-swift_ss01
今回はAutoLayoutは使用しない(赤枠の部分を参照)。
このままシミュレータで動かすとiPhoone6等では表示が崩れるが、そこは今回の主題とは離れるので気にしないこととする。

「通信開始」を押すと画像をダウンロードし、ImageViewに表示するというのが仕様だ。
通信開始ボタンとImageViewはViewControllerに接続しておく。

この段階ではViewControllerはこのようになっている。

ハイライト部分がStoryboardから接続した部分だ。

それでは早速通信処理を追加しよう。
まずは画像をダウンロードするメソッドを作成するし、通信開始ボタンがタップされたら呼び出すようにする。

1.セッションの作成を行う。

2.タスクを作成する。

3.通信が成功していたらImageViewに取得した画像を表示する。

4.セッションを終了させる。
 以前、NSURLSessionのメモリリークについても記事を書いた。
 http://[iOS] NSURLSessionのメモリリークに気をつける
 今回改めて試したところ、同じ現象は起きなかった。
 しかし、相変わらず公式のドキュメントには記述があるので、念の為に行っておく。
 参考:NSURLSession Class Reference

5.タスクを開始する。

当然ながら、基本的な流れはObjective-C版と変わらない。
しかし、Swiftで記述することでソースがスッキリして見えるのはやはり嬉しい点だ。

結果はこのようになる。
nsurlsession-swift_ss02

プログレスバーで途中経過を表示する
次は通信の経過をプログレスバーで表示してみる。
また、ダウンロードもメモリ上ではなく、ファイルとしてダウンロードしてみる。

まずはStoryboardでプログレスバーを追加する。
nsurlsession-swift_ss03
次に、そのプログレスバーをViewControllerに接続する。
今回はデリゲートを使用するので、NSURLSessionDownloadDelegateも追加しておく。

この段階では、デリゲートに必要なメソッドが実装されていないので、エラーが出てしまっている。
そこで、まずは中身が空のデリゲートメソッドを実装してしまおう。

通常なら、メソッドはViewControllerの中に実装してしまうのが当たり前であるが、extensionを使用してViewControllerクラスの外に記述しよう。

こうすることで、明確にデリゲートメソッドの処理が分離されてソースがとても見やすくなる。

それではダウンロード処理を記述しよう。
downloadWithFile()というメソッドを作成し、通信開始ボタンが押されたら呼び出すように変更する。
downloadWithDataTask()の呼び出しは削除しよう。

1.セッションを作成する。
 delegateには自身を指定する。
 また、Viewを更新する必要があるため、キューにはNSOperationQueue.mainQueue()を使用する。

2.タスクを作成する。

3.タスクを実行する。

処理はとてもシンプルだ。
これだけでファイルのダウンロードが行える。

現時点で実行すると以下のようにデバッグ出力が行われる。
write:2896 / 10335508 -> 10340182
write:1448 / 10336956 -> 10340182
write:3226 / 10340182 -> 10340182
finish
ここで、一つ気になった点がある。
それはURLSession(session: , downloadTask: , didResumeAtOffset fileOffset: , expectedTotalBytes: )が呼ばれていないということだ。

色々と調べてみたが、原因はよくわからない。
なので、ダウンロードを行う際の初期化処理等は上記のデリゲートメソッではなく、タスクの開始直前当たりに入れるのが良いだろう。
(今回は特に初期化は行わない)

必要ないので、上記のデリゲートメソッドは削除しておくことにする。

さて、ではプログレスバーの処理を実装しよう。

特に説明は必要ないだろう。
実行してみよう。
nsurlsession-swift_ss04
問題なく実行できた。