以前、NSURLSessionに関する記事を書いた。
[iOS] NSURLSessionを使って通信を行う
今回はSwiftで同じことをやってみる。
[iOS] NSURLSessionを使って通信を行う
今回はSwiftで同じことをやってみる。
画像をダウンロードする
今回もここから始めていこう。
まずはStoryboardでこのように設定する。
今回はAutoLayoutは使用しない(赤枠の部分を参照)。
このままシミュレータで動かすとiPhoone6等では表示が崩れるが、そこは今回の主題とは離れるので気にしないこととする。
「通信開始」を押すと画像をダウンロードし、ImageViewに表示するというのが仕様だ。
通信開始ボタンとImageViewはViewControllerに接続しておく。
この段階ではViewControllerはこのようになっている。
ハイライト部分がStoryboardから接続した部分だ。
それでは早速通信処理を追加しよう。
まずは画像をダウンロードするメソッドを作成するし、通信開始ボタンがタップされたら呼び出すようにする。
1.セッションの作成を行う。
2.タスクを作成する。
3.通信が成功していたらImageViewに取得した画像を表示する。
4.セッションを終了させる。
以前、NSURLSessionのメモリリークについても記事を書いた。
http://[iOS] NSURLSessionのメモリリークに気をつける
今回改めて試したところ、同じ現象は起きなかった。
しかし、相変わらず公式のドキュメントには記述があるので、念の為に行っておく。
参考:NSURLSession Class Reference
5.タスクを開始する。
当然ながら、基本的な流れはObjective-C版と変わらない。
しかし、Swiftで記述することでソースがスッキリして見えるのはやはり嬉しい点だ。
結果はこのようになる。
プログレスバーで途中経過を表示する
次は通信の経過をプログレスバーで表示してみる。
また、ダウンロードもメモリ上ではなく、ファイルとしてダウンロードしてみる。
まずはStoryboardでプログレスバーを追加する。
次に、そのプログレスバーをViewControllerに接続する。
今回はデリゲートを使用するので、NSURLSessionDownloadDelegateも追加しておく。
この段階では、デリゲートに必要なメソッドが実装されていないので、エラーが出てしまっている。
そこで、まずは中身が空のデリゲートメソッドを実装してしまおう。
通常なら、メソッドはViewControllerの中に実装してしまうのが当たり前であるが、extensionを使用してViewControllerクラスの外に記述しよう。
こうすることで、明確にデリゲートメソッドの処理が分離されてソースがとても見やすくなる。
それではダウンロード処理を記述しよう。
downloadWithFile()というメソッドを作成し、通信開始ボタンが押されたら呼び出すように変更する。
downloadWithDataTask()の呼び出しは削除しよう。
1.セッションを作成する。
delegateには自身を指定する。
また、Viewを更新する必要があるため、キューにはNSOperationQueue.mainQueue()を使用する。
2.タスクを作成する。
3.タスクを実行する。
処理はとてもシンプルだ。
これだけでファイルのダウンロードが行える。
現時点で実行すると以下のようにデバッグ出力が行われる。
それはURLSession(session: , downloadTask: , didResumeAtOffset fileOffset: , expectedTotalBytes: )が呼ばれていないということだ。
色々と調べてみたが、原因はよくわからない。
なので、ダウンロードを行う際の初期化処理等は上記のデリゲートメソッではなく、タスクの開始直前当たりに入れるのが良いだろう。
(今回は特に初期化は行わない)
必要ないので、上記のデリゲートメソッドは削除しておくことにする。
さて、ではプログレスバーの処理を実装しよう。
特に説明は必要ないだろう。
実行してみよう。
問題なく実行できた。
今回もここから始めていこう。
まずはStoryboardでこのように設定する。
今回はAutoLayoutは使用しない(赤枠の部分を参照)。
このままシミュレータで動かすとiPhoone6等では表示が崩れるが、そこは今回の主題とは離れるので気にしないこととする。
「通信開始」を押すと画像をダウンロードし、ImageViewに表示するというのが仕様だ。
通信開始ボタンとImageViewはViewControllerに接続しておく。
この段階ではViewControllerはこのようになっている。
ハイライト部分がStoryboardから接続した部分だ。
それでは早速通信処理を追加しよう。
まずは画像をダウンロードするメソッドを作成するし、通信開始ボタンがタップされたら呼び出すようにする。
1.セッションの作成を行う。
2.タスクを作成する。
3.通信が成功していたらImageViewに取得した画像を表示する。
4.セッションを終了させる。
以前、NSURLSessionのメモリリークについても記事を書いた。
http://[iOS] NSURLSessionのメモリリークに気をつける
今回改めて試したところ、同じ現象は起きなかった。
しかし、相変わらず公式のドキュメントには記述があるので、念の為に行っておく。
参考:NSURLSession Class Reference
5.タスクを開始する。
当然ながら、基本的な流れはObjective-C版と変わらない。
しかし、Swiftで記述することでソースがスッキリして見えるのはやはり嬉しい点だ。
結果はこのようになる。
プログレスバーで途中経過を表示する
次は通信の経過をプログレスバーで表示してみる。
また、ダウンロードもメモリ上ではなく、ファイルとしてダウンロードしてみる。
まずはStoryboardでプログレスバーを追加する。
次に、そのプログレスバーを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: )が呼ばれていないということだ。
色々と調べてみたが、原因はよくわからない。
なので、ダウンロードを行う際の初期化処理等は上記のデリゲートメソッではなく、タスクの開始直前当たりに入れるのが良いだろう。
(今回は特に初期化は行わない)
必要ないので、上記のデリゲートメソッドは削除しておくことにする。
さて、ではプログレスバーの処理を実装しよう。
特に説明は必要ないだろう。
実行してみよう。
問題なく実行できた。
コメント
コメント一覧 (2)
URLSession(session: , downloadTask: , didResumeAtOffset fileOffset: , expectedTotalBytes: )に関してはダウンロード処理が再開された時に通知されるようですー
ご指摘ありがとうございます。
Objective-Cで同じ処理を作った時は、通信開始時にそのデリゲートメソッドが
呼ばれていたのですが、Swiftになってからは文字通りResumeの時にのみ
呼ばれるようになったのかもしれませんね。