Swiftで遊ぼう! - 482 - URLSessionの基礎
- Swiftで遊ぼう!の前書き-> Life-LOG OtherSide
- 初心者はここから!-> 50オヤジでもできるiOS開発
- 私の本業、オフィシャルなブログ-> Life-LOG
- Swift 3 対応
2020年3月29日:Combineフレームワークの勉強のためDataTaskPublisherを使ってSwiftUIのデモに書き換えました。興味がある人は、Swiftで遊ぼう! - 1015 - URLSessionDataTaskPublisherの基礎 - Swiftで遊ぼう! on Hatena をチェックしてください
2017年4月7日:コードを修正*1
以前NSURLSessionの使い方を勉強していましたがいまはURLSessionに変更されています。ここのチュートリアルを勉強した後に次のページを読んでください:Swiftで遊ぼう! - 488 - URLSessionを使ってテキストデータをダウンロード - Swiftで遊ぼう! on Hatena
以前取り組んでいたNSURLSessionの勉強は次のページが発端です。
Swiftで遊ぼう! - 454 - Swift 2 NSURLSessionの理解から混沌にハマる...(URLSessionへ飛躍) - Swiftで遊ぼう! on Hatenaここで取りあげている一般的なNSURLSession利用のコードは、WWDC2015のセッションをみて取りだしたものです。
https://developer.apple.com/videos/play/wwdc2015-711/
// WWDC2015で紹介されていた一般的なNSURLSession利用のコード let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() let session = NSURLSession(configuration: sessionConfig) let url = NSURL(string: "https://www.example.com")! let task = session.dataTaskWithURL(url) { (data: NSData?, response: NSURLResponse?, error: NSError?) in ... } task?.resume() // Swift 3で使用するURLSession利用の一般的コード let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let url = URL(string: "https://www.example.com") let task = session.dataTask(with: url!) {(data, response, error) in ... } task.resume()
今日のテーマはURLSessionの使い方です。
新しいプロジェクトを作ります。「Simple View Application」を選んで、適当な名前を付けます。私は「URLSessionTest」にしました。Languageは「Swift」で、Deviceは「Universal」にします。
MainStroyboadを開いて、UIImageViewとUIButtonの2つのオブジェクトを画面に設置します。
当然Autolayoutでオブジェクトの位置決めをしてください。ここでは「Stack」を利用する必要はないので、基本的な知識で取り組んでください。
Swiftで遊ぼう! - 204 - フィリングを使ってレイアウト調整(Auto Layoutのまとめ) - Swiftで遊ぼう! on Hatena
基本的にオブジェクトを画面のセンターに位置決めして上部のマージンを設定すればいいんです。Image Viewは大きさを一定にします。heightを「240」でWidthを「240」の正方形を確保します。
次にボタンは「ダウンロード」に改名します。そして空のImage Viewにデフォルトのイメージをロードさせます。
アプリのテスト環境は「iPhone 7」にします。すると、プロジェクトで使用するイメージのサイズは2種類でいいんです*2。先ず、プロジェクト・ナビゲータでAssets Xcassetsを選択して、下部にある「+」ボタンを選び、「New Folder」を選択します。フォルダーの名前を「Placeholder」に変更してから「+」ボタンを再び選択して「New Image Set」を選ぶと「1X」「2X」「3X」の空のスロットができます。
次に何でもいいので「png」イメージを用意します。オブジェクトのサイズを「240×240ピクセル」にしているので、1Xはそのまま、2Xは「480×480ピクセル」、そして3Xは「720×720ピクセル」の画像を用意するのですが、ここでは2Xスロットだけセットします。
このイメージをImage Viewに設定するのは非常に簡単です。Image Viewを選択した状態でアトリビュート・インスペクタを開きます。Image Viewの「Image」を選ぶと、Assets Xcassetsに設定したイメージがメニューに出てきます。私の場合は「backgroundimage」です。それを設定するとMain.storyboardのイメージが変化します。
もう一つだけ設定しておくべき項目があります。そのままサイズ・インスペクタを開きます。項目の下のほうに「Intrinsic Size」があるので、「Placeholder」を選び、WidthとHeightをそれぞれ「240」を選びます。
Main.storyboardにオブジェクトを並べたら「Ctrl + ドラッグ」でViewController.Swiftの所定の場所に@IBOutletと@IBActionを作ります。
お決まりの「// MARK: -」を付けるのを忘れないようにします。
Main.stroyboardのオブジェクトと関連付けられていれば、プロパティやアクション前に「●」が付いています。これが付いていればランしたときにインスタンス化されます。
次は、ネットにある画像をダウンロードする関数を実装します。「getImage()」という関数を作って、ありきたりなURLSessionクラスをコードします。
func getImage(){ let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let url = URL(string: "https://s3.amazonaws.com/ CoverProject/album/ album_david_bowie_lets_dance.png") let task = session.dataTask(with: url!) { (data, response, error) in // ここで具体的な作業をさせます。 } task.resume() }
これがお決まりのコーディングです。URLSessionクラスのメソッド「dataTask()」はURLクラス情報と関数(クロージャー)を引数として受け取って、クロージャーの仕事(task)をさせるという、ちょっとプログラミング素人には理解し難いコーディングになっています。このクロージャーは「(Data?, URLResponse?, Error?) -> Void」のことで、通信中にエラーは当然生じるものとして扱っています。
実際のコードを考えてみます。当然パラメータ名は自由にできるのですが、混乱しないように(data, response, error)とするのが一般的です。
まずdataはオプショナル型Dataなので存在するかどうかを最初に判断させます。
guard let getData = data else { // dataが存在しなければキャンセルするステップです。 session.invalidateAndCancel() return } // dataが存在すればgetDataとして処理
そして、dataが存在するのであれば、データのダウンロードは時間がかかるのでバックグラウンド・キューでさせるのですが、キューの意味が分からなければSwiftで遊ぼう! - 302 - マルチスレッド(まとめ) - Swiftで遊ぼう! on Hatenaで勉強しましょう。
DispatchQueue.global(qos: .userInitiated).async { let image = UIImage(data: getData) DispatchQueue.main.async { [weak self] in self?.imageView.image = image } }
これを整理すれば次のメソッドになります。
func getImage(){ let config = URLSessionConfiguration.default let session = URLSession(configuration: config) let url = URL(string: "https://s3.amazonaws.com/ CoverProject/album/ album_david_bowie_lets_dance.png") let task = session.dataTask(with: url!) { (data, response, error) in guard let getData = data else { session.invalidateAndCancel() return } DispatchQueue.global(qos: .userInitiated).async { let image = UIImage(data: getData) DispatchQueue.main.async { [weak self] in self?.imageView.image = image } } } task.resume() }
そして、この関数を@IBActionにコードします。
@IBAction func downloadImage(sender: UIButton) { getImage() }
これでコーディングは終了!
ランしてみよう!
ダウンロードができました*3。
次にURLSessionのまとめをしているので次のページに進んでください。
yataiblue.hatenablog.com
*1:2017年2月26日:Swift 3向けのコードに変更
*2:理由がわからなければSwiftで遊ぼう! - 249 - iOSの座標システム: 2020年3月 - Swiftで遊ぼう! on Hatenaで説明しているScaling値を確かめましょう。
*3:以前はサンプルイメージが保存されているサイトがインセキュアだったためダウンドーロできませんでした。その場合はATSを使って例外サイトの登録をする必要があります→Swiftで遊ぼう! - 455 - Swift 2 NSURLSessionまだ全然わかっていない...ちょっと分かったかな(ATS) - Swiftで遊ぼう! on Hatena