ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Xcodeプレビューをマスターする
Xcode 11ではユーザーインターフェイスのプレビューがエディタに直接表示されるため、編集、デバッグ、実行のサイクルをシームレスなワークフローで進めることができます。このセッションでは、プレビューの仕組み、SwiftUI Appの構造をプレビューに最適化する方法、既存のビューとビューコントローラをプレビューに対応させる方法について説明します。
リソース
関連ビデオ
WWDC19
-
ダウンロード
(音楽)
(拍手) こんにちは XcodeのPreviewsについて話します すでに 今回の様々なセッションで XcodeのPreviewsを 目にしているでしょう 今日はPreviewsそのものの話です 私はアントン 後ほど 同僚のネイトも登壇します XcodeのPreviewsの機能や 活用方法について お話しする予定です SwiftUIを用いた 最新のアプリケーションや 従来のアプリケーションにも役立ちます まず これを見てください
例えば デザイナーがこんな画面を 試作してきたとしましょう それを元に作業し ビルドして― 再び デザイナーに見せます コードを実行して この画面が出るまで 進めていきます そして これを見せる デザイナーは言います “ボタンの青色は もっと濃いほうがいい気がする” 直すのは簡単です Xcodeで編集するだけです 再び実行して この画面が出るまで進めて デザイナーに見せます “かなり よくなったけど―” “文字の余白を もう少し詰めたいな” お分かりですね こうした繰り返しは いつものことです 誰もが経験します いい物を作るための過程です ですが かなり時間がかかります 何に時間が かかるかというと 小さな修正や フィードバックではありません 時間がかかるのは ビルドや実行です そして 見たい画面にたどり着いて 結果を確認することです
もう1つの例を挙げましょう
デザイナーとの作業が終わりました 仕上がりには満足しています しかし まだ― デベロッパの仕事は 終わりではありません 動作に問題があっては いけないからです つまり どんな設定で実行しても 優れたビューを 維持しなくてはなりません 例えば ダークモードで見た場合や
コンテンツサイズを変えた場合
デバイスが違う場合でもです
様々な条件で UIの動作を確認しつつ 最良のデザインを 維持していくのは大変です そして App Storeへの公開に こぎ着けなくてはなりません Xcodeチームは この問題について考え 行き着いた答えが Previewsです これは Xcodeの新機能です ビルドして 実行し 変更を確認する時間を 最小限まで 短縮してくれる機能です これにより よい物を作るという 本来の作業に 多くの時間を使えます
では 実際に どうするのでしょうか Previewsを実行する時― Xcodeは特殊なビルドを行います
Xcodeは 常に 作業対象を把握しているので そのビューやファイルだけを コンパイルできるのです そして Dynamic replacement機能で アプリケーションに戻します
再コンパイルするコードの量は 全体に比べると ずっと少なくて済みます だから 変更するたびに 実施できるのです 変更へのフィードバックが 大幅に高速化します 変更の内容によっては さらに最適化できます 文字列や数字などの リテラル値だけの変更なら 再コンパイル不要です 実行中に 新たな数値を 入れるだけなので 迅速なフィードバックが得られます
ここで 注意点があります
Previewsでは 実行時の見え方を 推測しているのではありません 実際に コードを実行しています
だから 実行時に利用できる コンテキストは すべて使えるのです カスタムアセットも描画できます カスタムロジックを使いたいことも よくありますが もちろん使えます setUserDefaultのような ランタイム設定も Previewsで使えます
表示すべきものを Xcodeに知らせるには?
見たいビューや設定を伝える― わずかなコードを書けばいいのです PreviewProviderに適合する― 型を実装するだけです SwiftUIフレームワークの一部です Previewsのプロパティを要求されます コンテンツを戻します ここで 何を戻すかは完全に自由です
このコードは アプリケーションの一部なので 他の部分と一緒にコンパイルされます 設定コードに関しても ビューと同じことが言えます 従って カスタムロジックも カスタムリソースも ランタイム設定も使えます コードを使って設定する利点は それだけでは ありません 例えば この設定コードはSwiftUIです SwiftUIのビューの作り方が分かれば 設定も簡単でしょう
それに 一度書けば チームで共有が可能です つまり チーム全体に有益なのです
最後に アプリケーションは 常に進化します ビューやAPIに変更があったとします その際はコンパイラが ビューとプレビューとの同期を 確認してくれます
Previewsの仕組みを 簡単に説明しました この機能を最大限に 活用する方法について ネイトが話します (拍手)
Previewsはコードです その書き方を話します
みんなで 動物園に 行くことになりました
動物を 1種類も見逃したくありません 私たちはデベロッパですから 動物追跡アプリケーションを作りました
私が作業しました その メインのUIは 動物のリストです リスト内に多数のセルを表示します
ここまで できました
セルのプレビューが見られます
今は 実行先として iPhone XSを選択していますが あらゆるデバイスで確認したいですね 私の端末は iPhone SEです 実行先を SEに変えてもいいですが Previewsには別の機能があります previewDeviceです
このメソッドに デバイス名を渡します すぐ キャンバスに そのデバイスが表示されます iPhone SEで見てみると 問題が見つかりました 文字の右端が切れています 直しましょう “HStack”を“VStack”に変更します
すぐに 直した結果を表示してくれます
アントンの端末はiPhone XRです 問題ないか確かめましょう previewDeviceに渡す引数を変更します もっと簡単なのは― ビューをグループにする方法です Command + クリックで “Embed in Group”を選びます 2つ目のインスタンスを追加して iPhone XRの previewDeviceを 呼び出します
キャンバスを見ると― 2つのデバイスが見られます
動物の学名をイタリック表記に― 直したいと思います
どちらのデバイスでも 正しく表示されていますね 簡単でしょう
(拍手) 実際のデバイスで プレビューできるのは便利です しかし セルなどの小さなビューは その部分だけを見たいですね 不要な部分を消しましょう それには previewLayoutを使います このメソッドには― 3つの引数を渡せます 1つは デバイスの指定です 今 キャンバスに 表示されているものです 次に プレビューを表示させる サイズを指定できます 別のビュー内に 埋め込むビューを作る時は 非常に便利です 最後は sizeThatFitsです コンテンツに応じて サイズを決定させたい時に 便利な方法です セルはリストに埋め込まれます リスト内のセルのサイズは コンテンツに応じて― 変更可能なので sizeThatFitsを使いましょう
すぐに キャンバスに表示されます
右下のプラスボタンで拡大できます
2つのテキストがあります “アカギツネ”と“イヌ科”です
やや見にくいですね 区別しやすく直しましょう “アカギツネ”を太字にします Command + クリックで “Inspect”を選びます Weightを“Bold”にします
ソースエディタに コードが追加され プレビューも更新されます いいですね
ユーザが 文字サイズを変えた場合― “特大”にしたらどうでしょう プレビューで見てみたいと思います Previewsは SwiftUIの一部なので その利点を もれなく利用できます environment modifierを用いて
sizeCategoryを “extraLarge”にします
サイズを簡単に変えて すぐ見られるのは便利です しかし 一度にすべてのサイズ区分を 表示させられると もっといいですね ビューをグループ化すれば それぞれのサイズの セルを作れます でも もっといい方法があります
ForEach機能を使います Command + クリックで “Repeat”を選びます すると 0から5までの プレビューが出ます ここでは 各サイズ区分の プレビューを表示させます それぞれのケースに 環境を指定します sizeCategoryの KeyPathの値を合わせます このように キャンバスを見ると すべてのサイズ区分で表示されます (拍手)
このプレビューで 特小のサイズ区分を見てみると 一般名が目立たないのが気になります 文字を大きくしましょう キャンバス上で Command + クリックします “Inspect”を選択して― Fontを“Title”にします
コードが追加され キャンバスも更新されました いいですね 複数のプレビューを見る時に 問題となるのは それぞれの区別が難しいことです コードのどの設定が どのPreviewsに対応するのかを 把握しておかなければ なりません
この問題を解決するのが previewDisplayNameメソッドです 表示するサイズ区分の名称を使います 各プレビューの下に サイズ区分が出ました
(拍手) すばらしいでしょう
PreviewsのAPIは 簡単かつ強力です これを最大限に活用する方法を アントンが話します (拍手)
では このデモを引き継ぎ 動物のセルを仕上げてしまいましょう まずはアカギツネの画像の プレースホルダです このアプリケーションのデータは ネットワークから取得する予定でした ですが未完成です 表示するデータがないため プレースホルダを使います こうした文字列は簡単ですが 画像となると複雑です プレビューのため アセットを 追加することになります すると 製品にも アセットを含めることになり 望ましくありません 余計な物は排除したい 今年 Xcodeには この問題を解決する― 新機能ができました Development Assetsです まず プロジェクトエディタを開きます
“TARGETS”の中に “Development Assets”があります すでに 画像の入った アセットカタログが 設定されています テンプレートを使って ゼロから作る場合― これは 設定済みです 既存のアプリケーションでも 簡単に追加できます それでは カタログのアセットを プレビューデータで見てみましょう プレースホルダで使用する アカギツネの画像です AnimalCellファイルを開きます
そして―
プレビューします
すでに 画像の名称が入っているので ここを“Text”から“Image”に 変えるだけです
プレビューに画像が出ます いいですね ですが ちょっと処理をして 目立たせましょう 簡単な SwiftUIのコードを使います シャドウとオーバーレイを付けました コードはどうなったでしょう このセルのビューは 画像処理のコードが目立ちます このせいで 詳細が見づらくなるのは困ります 抽出するため Command + クリックで― “ExtractedView”を選びます ファイル内のビューを探してくれます 名前を“AnimalImage”に変えます
画像名を引数として与えます スクロールするとあります 簡単ですね ここに入力します
できました
(拍手) いい出来でしょう プレビューは変わりませんが 上にスクロールすると― 画像処理以外の詳細が ずっと見やすくなっています ここまで このビューだけを 見てきましたが 実際 ユーザには このようには見えません このビューは リストの一部として 表示されるものです その作業をします すでに作ってあります この“AnimalList”ファイルです それぞれの動物のセルを 表示できるように シンプルなリストを作りました この部分を“AnimalCell”に変えます 表示されました 実際の画面に近付きました
ですが まだ1種類だけです そこで このリストに もっとデータを追加して ユーザが見る画面に 近付けたいと思います やってみます Previewsの設定コードを見てみると 1つの要素のみの配列で リストを表示しています そこで この部分のコードを書き換え 追加すると 3つセルが出ました これを繰り返せば 増やせますが 全部同じでは やはり 実際の画面とは違います 動物の名前の長さや色は 様々です それがどう見えるか 知りたいのです では どうするか? プレビューは アプリケーションの 一部として実行されます 従って ネットワークにつなぐことで データを取得することもできます しかし 問題があります まず― まだ コードができていません さらに問題があります このビューの作業をするたびに オンラインでサービスを 使う必要があります よい方法とは言えません 望ましいのは データをキャッシュに入れて 他の構成要素を要求することなく 可視化することです 先ほど 作業して― JSONファイルで キャッシュを作りました この シンプルなファイルに 動物のデータが入っています これは 実際の製品には 含めたくないので 後ほど 開発用アセットに 追加する予定です あとでやります 今 すべきことは これをロードするだけです コードを追記して このJSONをロードします JSONDecoderで解析します このデータ配列を… ここは閉じて― この配列を“Self.sampleAnimals”と 置き換えます
プレビューを更新すると 動物が表示されました (拍手) ありがとう 実際の画面に かなり近付きました 問題点も すぐ分かります この“ユキヒョウ”の名前は 長いので調整したいですね それから タイトルが大きいので もう少し 空間が欲しいです 上下に余白を入れましょう すべて セル内の修正ですから そのファイルに切り替えます すると どうなるか? 先ほどのプレビューは消え セルのプレビューに戻りました リストは見えません できればセルを編集しながら リスト内の見え方を確認したいのです Previewsを追加する方法もあります どんなコンテンツも表示できますからね しかし 同じコードをいくつも― 複製しなくてはなりません いい方法があります どうするかというと もう一度“AnimalList”に戻ります 左下にあるピン型のボタンを使います クリックすると プレビューがピン留めされます この状態で別のファイルに移動すると どうなるか?
そのままです (拍手) ヘッダの表示は このプレビューは 別ファイルのものだと言っています そのとおりですね 元のプレビューを見たければ スクロールしてください リストはありません (拍手) Command + クリックで “Inspect”を呼び出します アラインメントを修正できます 余白を加えると
こうなります
これは ちょっと余白が大きすぎます また 戻って余白を減らしましょう
いいですね これをキープします 次は セルを選択した時に使える― 一連のアクションに関する作業です 別ファイルを作ってあります “SelectableAnimalCell”です AnimalCellModelのデータは 一時的な物で汚したくありません そこでラッパーを追加して selectedも追加します この別のビューを 使用することにします モデルを受け取り AnimalCellを表示し 選択を確認して アクションを表示します 情報やカメラなどのアイコンです ピンを解除すると セルのプレビューが2つあります 選択と非選択の状態です これが非選択 これが選択です これで作業してもいいですが やはり リストで見たいですね そこで リストに選択を追加します “AnimalList”に行き
SwiftUIは このようなデータを 状態変数で扱います ここにステートを追加します 選択のデータを保管するためです
もう1つ コードを追加します このデータは 選択されたモデルを明示しますが 各セルは ブール値を取るからです ここに追加します この2つの作業をして “AnimalCell”を
置き換えます
これでプレビューを更新すると どうでしょう 変わりません これはなぜでしょうか? 選択が任意だからです 今は何も選択されていません だから 反映されていないのです Live Voteをクリックして
どれか選択することもできます アイコンが出ます 予想どおりです ですが もしここで… ありがとう 静的なプレビューを ビルドしたい場合は? つまり 変更を加えた時に 選択状態も忘れずに チェックできるようにです 静的プレビューを作るには コードを書き換えます このデータはプライベートなので プレビューから修正できません では どうするのでしょう これをバインディングにします まず AnimalListの中に プライベートのビューを作ります ここにすべて入れます “Content”とします このファイル内でのみ使えるからです そして 今実装したものをすべて このビューの中に移動させます そして最後にAnimalListに bodyを追加します Contentのビューを実体化するものです 選択状態とバインドさせるのです AnimalListではなく AnimalList.Contentの プレビューに切り替えます
更新すると
選択状態のある 静的プレビューが出ます “AnimalList”の プレビューをタップすると 非選択状態の見た目も確認できます Live Voteを用いて 動きを確認しながら 作業することもできます (拍手) ありがとう (拍手) ここまでXcodeの機能を見てきましたが まだ できることがあります ネイトに話してもらいましょう (拍手) アントン ありがとう
アプリケーションを 新たに作る人ばかりでなく すでに開発中という人も多いでしょう SwiftUIは UIKit AppKit WatchKitとも統合しやすく PreviewsのAPIはSwiftUIの一部です ですから Previewsは すべてに有効です
動物園アプリケーションで アントンが作った― Infoボタンをタップします すると動物の詳細画面が 表示されます UIViewControllerとして 書かれた画面です
“AnimalViewController”です
これが コードです Command + Returnで キャンバスを閉じて ファイルを切り替えます
中身はこんな感じです ビルドと実行はせずに プレビューを作ります Previewsは コードですから このファイル内に 作ることもできます 今回は 新規ファイルを作ります Command + 0でナビゲーターを開き 任意のグループ内にファイルを作ります 右クリックで “New File” “Swift File”を選び “AnimalViewControllerPreviews”と 名付けます
プレビューを書くためには SwiftUIをインポートします
ここで プロトコルにConformantを 追加する必要があります 今回は 適合する新規の型を作成します “AnimalViewControllerPreview”です ここで実装しなくては ならない物があります 静的プレビューのプロパティです ここからビューを返します 欲しいのは AnimalViewControllerに 埋め込まれたビューです
SwiftUIでは UIViewControllerを Swiftのビューに― Representableの形で埋め込めます “Integrating SwiftUI”も ご覧ください 今回は UIViewControllerの 代理としたいので UIViewControllerRepresentableに Conformantを追加します 便宜上 “PreviewProvider”を “AnimalViewControllerPreviews”に 並べて追加します
目的を達成するため このプロトコルは 3つの実装を要求します まず UIViewControllerの型を 指定することです ここでは “AnimalViewController”です 次に “AnimalViewController”を どう作るかを 記述する必要があります ダークモードや ダイナミックフォントなどの コンテキストの中でです
ここでは すでに ラッパークラスを追加してあり そこから ロードします
最後は UIViewControllerの更新です ビューコントローラの見た目を 環境に応じて変化させるためです プレビューだけでいいので ここはブランクのままにします
これでプロトコルに Conformantを追加できたので メソッドを実装できます
具体的には 適合する型の インスタンスを返します “AnimalViewControllerPreviews”です 数行のコードで UIViewControllerの プレビューを見られます 見てみましょう ナビゲーターを閉じて キャンバスを開きます
新たなメソッドを追加したので リビルドが必要です キャンバスにプレビューが 表示されました ありがとう すばらしいですね Swiftで書いた UIViewControllerのプレビューです
しかし これを見ると問題に気付きます 文字が非常に読みにくいです 読みやすくするため 画像とテキストの間に 半透明のアンダーレイがあります 透明度が高すぎるようです 不透明度を上げる必要があります 変化が分かるように プレビューをピン留めして ファイルを切り替えます
underlayViewのアルファ値を 0.5に変更します すぐに キャンバスの プレビューが更新され 変更が反映されました XcodeのPreviewsは あらゆるSwiftコードで有効なのです さらに アントンが話したとおり リテラル値の場合は 再コンパイル不要です UIAppKitでも WatchKitでも同じです (拍手) ありがとう
アントンの AnimalActionViewControllerにも 私がプレビューを追加しました 見てください プレビューのピン留めを解除します 左下のボタンをクリックします アクションのファイルに切り替えます プレビューが表示されています 右端のボタンについて検討し “i”の画像を直したいと考えました 合っていないためです では 修正しましょう “AnimalActionViewController”を開き 昔懐かしいObjective-Cで これを書きました (笑い声) どうもありがとう いい言語です
情報ボタンに表示する画像を “info.circle”に変えます
再び プレビューに切り替え 更新します Objective-Cで書かれているので Xcodeは 差分更新や ホットスワップはしません 通常のリビルドをしようとします それでも非常に高速です リビルドして実行して確認するよりも はるかに速いのです このように SwiftUIや Swiftファイルだけでなく Objective-Cのコードにも有用なのです Xcodeが理解できる どんなファイルもです
(拍手)
Previewsによる 作業の高速化を見てきました ですが アプリケーションの アーキテクチャを 少し変えることで さらに 力を発揮します 動物園アプリケーションの 1つの型を例に取ります AnimalCellModelです これを使って 動物のセルを 表示させることができました SwiftUIのAPIは有能です そして―
このメソッドは簡単に実装できます このモデルを使う利点があります どのフィールドに どのデータが表示されるかが 非常に明白になるのです
しかし オブジェクトを ビューに直接― 渡すことも可能でした そうしなかった理由は2つ
1つ目の理由は ビューモデルを使うと プレビューの追加が容易なこと PreviewProvider実装の 優れたパターンは ビューモデルの静的配列を 追加することです 静的プレビューの プロパティの実装では ビューモデルの配列を 繰り返すことです 異なるレイアウトになる 新たなデータ設定に― 遭遇した時に有用です ビューモデルを作って 配列に追加するだけで 新たなプレビューが キャンバスに表示されます
ビューモデルの使用を決めた― 2つ目の理由を説明します その前に哲学的な気分に浸りましょう
モデルには豊富な オブジェクトグラフが含まれます 1つの動物モデルオブジェクトは その系統に属する 多数の動物の1つにすぎません
一方 モデルオブジェクトには ゲノムも含まれています
この情報をどう表示しますか?
一度に全部は表示しません
例えば セルには ゲノムを入れたくありません 情報が多すぎます それよりも 最も重要な 情報だけを抽出して それを用いて ビューを作成したいのです また 1対1で抽出するのではなく データを変換することも多いでしょう ここでは 2つのフィールドを取り出し 属と種を組み合わせた 1つのテキストにしました
このような 変換や抽出は エラーの元ですが ビューモデルなら明確です
このビューモデルは モデルオブジェクトから 構成されています
思うとおりに データが抽出され 統合され ユーザに表示されているのが明白です
この明確さは非常に有益です テストが容易になるからです 異なる方法で ユーザに示す必要のある― 新たなモデルオブジェクトでも XCTestを使えます 新たなテストケースを追加して ビューモデルから モデルオブジェクトを作成します そして ユーザに必要なデータを 示せることを確認すればいいのです これが ビューモデルを使った 2つ目の理由です
このことは 何を意味しているのでしょう
優れたアプリケーションを作るには オブジェクトグラフを利用します モデルレイヤの中に豊富にあります 最も重要な情報を 抽出してユーザに示します しかも 美しく示すのです
ビューモデルを使えば とても簡単です 次のような流れで 使うことができるからです
まず― ビューモデルを構築します
エラーが起きやすく 何度もテストが必要です 見せたいデータが含まれるか 確認が必要です 次に 異なるレイアウトの ビューモデルにそれぞれ― プレビューを追加します すぐに キャンバスで 正確に表示されていることを 確認できます 最後に XCUIのテストで アプリケーションの動作を確認します
パフォーマンスの話をしましょう
Previewsはコードにすぎません プレビューを描画する時 勝手な処理を実行したくはありません 100万番目の素数の計算は不要です XcodeのPreviewsでは didFinishLaunchingWithOptionsが 呼び出されます 大量の無関係の処理は望みません また UIの序列を設定したくありません ただ キャンバスで プレビューを見たいのです そこで アプリケーションを UIWindowSceneDelegateに適合させ willConnectToメソッドを実装します そしてUIの序列を設定します プレビューが高速化し デベロッパに有益なだけでなく ユーザにも利点があります バックグラウンドで 余分な処理をしないのです 必要な仕事だけをするので バッテリーも長持ちします
(拍手) では まとめです プレビューの書き方を説明しました とても強力で― SwiftUIを利用できます
高度な方法も説明しました ファイルを切り替える際の ピン留めなどです 次に 開発用アセットを見せました これでテスト用のデータを 製品に含めることなく 豊富なプレビューができます 最後に Previewsは SwiftUIやSwiftだけでは ありません Xcodeが理解する あらゆるファイルで利用できます (拍手) ご清聴ありがとうございました (拍手) ラボもよろしく
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。