ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
Swift Playgrounds用の魅力的なコンテンツを作成する
Swift Playgrounds用に作成されたガイド付きのインストラクションコンテンツを作成する方法について解説します。完成したサンプルコードプロジェクトに対し、ガイドを追加する方法についても解説しますので、是非ご覧ください。研修センターにタスクを追加して、関連コードやオプションの実験タスクがわかるようにし、学習者が自分のコードでプロジェクトを拡張できるようにする方法を紹介します。
リソース
関連ビデオ
WWDC22
-
ダウンロード
♪ ♪
こんにちはStephanie Anguloです Marcus Jacksonです Swift Playgroundsチームのエンジニアです 今日はこのSwift Playgrounds 4が創り出す 魅力あるツールについてお伝えします これはiPadとMacのApp開発で紹介されました App StoreのApp構築を学ぶのに最適な方法です 当チームはApp開発の基礎を学ぶのに役立つ 指導書およびサンプル製品を多数発表しました 観察できるデータモデルを使い 動的なSwiftUIAppの構築 アニメと図形を使用した カスタマイズビュー非同期データの取得など 高度なトピックについて取り上げています 今日のセッションでは 新教育システム概要を説明し プロジェクトのモジュールを 使ってコンテンツを書き ウォークスルーや実験タスクで 実体感のある学習体験を作り上げます さあ 始めましょう 「Appを使い続ける」を 学習者が完了したとします 最後に「絵文字」というAppが表示されます ここにお気に入りの動物全てを登録し 色とサイズを変更して 動物をタップすると「クリーチャーダンス」で 経過を追うことができます
これは楽しいですが 実際のパーティーの雰囲気に したいと思っています まず先に紹介できる追加機能を説明しましょう
「クリーチャーダンス」に コードを追加しました パーティーにはダンスフロアが必要です 10x10 グリッドをビューの背景に設定しました
グリッド内の各タイルは カスタムビュー修飾子を使い ランダムに色を更新します ほら 格好いいでしょ?
また お気に入りの動物が私たちの手助けなしに 踊れるように動物の大きさ 位置補正 回転を アニメ化するための カスタム修飾子を作りました
アニメはこれらの修飾子で 永久に繰り返し設定されますrepeatForever, つまり 動物は新しいフロアで 一晩中ダンスできます
最後にダンスフロアを本格的に明るくするため 視点の上部にアニメの ミラーボールを追加しました
最終調整を加えることで 最高のダンスパーティーを実現しています 私はこのプロジェクトを かなり変更をしましたが カスタムビュー修飾子の 詳細はみていませんでした 学習者にどう説明したらよいでしょうか? Appleのドキュメントを教えることもできますが Swift Playgroundsの プロジェクトコードと一緒に これらの考えを教えることもできます 私たちのチームは学習者が魅力的なApp内体験の 作成を手助けできるように この新しい教育システムを作りました Swift Playgrounds 4で学習内容を構築する 方法について説明をします 使用する前に少しご紹介しましょう 学習者がSwift Playgroundsで コンテンツをまず開いたとき オプションのウェルカムメッセージを使い フレンドバイトから プロジェクトに紹介できます ウェルカムメッセージは画面左側にある ソースエディタの上部に表示され ラーニングセンターが画面右側に表示されます
ラーニングセンターはコンテンツを説明する 画像や説明文を追加できる指定領域です
ウェルカムメッセージと ラーニングセンターでは SwiftUIの色 形 アニメを使い ジャムを解消することを 学習者に知らせます
ラーニングセンターには タスクのセクションもあり 学習者を支援するための目標をコード化します これらはコンテンツの基本的な構成要素です
ラーニングセンターの タスクボタンをタップすると 教育システムがSwiftファイルを開き 先頭に学習資料が記載された カードが表示されます このカードはテキスト 画像 コード スニペットを含みます 次にMarcusがウォークスルーと実験の 2つのタスクタイプについて説明します
当社教育システムが提供する 高いレベルのものです 適切な説明とタスクを使うことで 学習者に魅力的な教育体験を作り上げます さて 独自のコンテンツ作成を始めるには ガイドモジュールについて 説明する必要があります デフォルトではswiftpmプロジェクトは 全てのソースコードをルートに保持します 教育システムを活用するためプロジェクトを アップグレードするには ファイル構造の変更が必要です まず Appモジュールを作成する必要があり 作成したらプロジェクトの ソースコードとアセットを そこに移動します プロジェクトルートに swiftパッケージは残します
次にガイドモジュールを作成します これはモジュールファイルと 同じレベルの必要があります ガイドモジュールの中に ガイドファイルが必要で ラーニングコンテンツの 全要素がここに含まれます 私はガイドファイルをすでに始めています では これまでの内容をチェックしてみましょう
これにはディレクティブと マークダウンが含まれます ディレクティブはマークダウンの拡張で 文字列などのプリミティブ型マークダウン要素 その他のより複雑な型を 取り込むことができます
ディレクティブは他のそれの コンテナとして機能しますが 教育システムでUI要素を表すこともできます ガイドファイルの初めに 必要な指示を追加しました これはファイル全体に適用されています これは すべての指示の メインコンテナとしなります この引数には タイトルアイコン 背景画像 最初に開くファイルが含まれます ウェルカムメッセージをガイドブックの指示で 追加しましたこれはオプションで プロジェクトを開いたときに 最初に受講者に表示されます その下にステップディレクティブに囲まれた ガイドディレクティブを追加しました ガイドディレクティブは ステップのコンテナとして 機能しラーニングセンターと タスクに表示される コンテンツにマッピングされます ラーニングセンターで画像や 説明文の追加を始めるには ContentAndMediaディレクティブが必要です
それで ダンスフロア 素敵なウェルカムメッセージ ラーニングセンターの紹介を 追加しパーティーをしました Marcusパーティーに行きたくない? もちろん 創造動物のパーティーに なんて良いフロアでしょう この効果は本当に素晴らしいもですが まだ学習中の人には難しいかもしれません ウォークスルータスクを コードの説明に使います 完全攻略ガイドの1ページから始めましょう 後から残りの入力方法を説明します Stephanieがガイドブックの最初の部分と ウェルカムメッセージをすでに見せています タスクを作成に必要な最初のディレクティブの ステップディレクティブはすでにあります ここはウォークスルーの 内容が保存される場所です ステップ作成には2つの ディレクティブが必要です コンテンツとメディア ディレクティブを追加します この指示には右側のラーニングセンターに入る マークダウンが含まれます 本文には任意のマークダウン を含めることができます より長い文章やより大きいイメージで あなたのテーマを取り上げる 助けになるかもしれません ここはコンテンツやメディア ディレクティブを表示します この例では領域は小さく見えますが このビューは下に広がり スクロールビューがあります これで文章の長い部分の記述や 図形など複雑なコンテンツの表示にも適します コンテンツとメディアを作成した時点で 次に必要なディレクティブの タスクを追加できます タスクグループにある別の ディレクティブに追加します タスクグループはタスクをまとめる場合に ステップ内に配置できる 任意のディレクティブです 複数のファイルやさまざまな種類のタスクで 同テーマを扱うコンテンツが ある場合を考えてください タスクグループ内に 短いテキストを追加できます これはラーニングセンターで サブタイトルで表示されます
プレイグラウンドにそれを 表示する方法を説明します
タスクグループとサブタイトルが表示されたら タスクディレクティブの追加を開始できます タスクにはいくつかの引数があり 最初の引数はtypeです これで 教育システムは このタスクを表示するときに 生成する UI を知ることができます すべてのタスクにはIDが必要です IDの文字列は任意に指定できます ガイド内の各IDは固有のもの である必要があります タイトル引数も文字列です これは固有のものである必要もありません これはタスクカードUIにより与えられます 最後にラーニングセンターに 学習者がタスク開始時に開く プロジェクト内のファイルを通知します プレイグラウンドにタスクが どう表示されるか説明します タイトルはボタンの内側にあり ウォークスルーファイルが その上に表示されます ウォークスルータスクが書かれました 最初のページを加えましょう ページディレクティブはタスクの本文内にあり 次の必須引数を持ちます ID引数はタスクのIDと同様に動くため ガイドファイル全体で 固有である必要があります タイトル引数はタスク引数と 動きがよく似ていますが ページ上でタイトル文字列を空白にしておくと 指示システムがページを表示するときに タスクのタイトルを使用することができます ページ内ではcontentやmedia ディレクティブと同様に マークダウンテキストを追加 できますがタスクビューは ラーニングセンターより はるかに小さくなります 学習者には難しい場合があるので 複雑な画像は使わず テキストを短くしてください Swift Playgroundsによる ウォークスルーの最初です 最初のウォークスルーはほぼ完了していますが 最後のスクリーンショットに 示すようにコードを強調する 方法の説明が必要です クリーチャーダンスSwiftに マーカーの追加が必要です ウォークスルーが表示されたら 最初のカスタム修飾子である AnimatedScalingEffectを 強調します コードの前後にコメントを追加し 行を強調します まず複数行のコメント構文の スラッシュスターで始めます コメントにはシャープ ダッシュ コード ダッシュ ウォークスルーの後に括弧がきます 括弧内に強調するページディレクティブの IDを入力します この場合は 1.modifierです
では プレイグラウンドで試してみましょう 絵文字Appプロジェクトを開きます
プロジェクトを開くと左側にソースエディタ 右側にプレビューが表示されます ウェルカムメッセージが ソースエディタ上に表示され バイトバディがコンテンツの概要を示します 詳細ボタンをタップします
ラーニングセンターに 右プレビューが切替わります ContentAndMedia directiveに 書いた文章が一番上です 下はタスクグループです ウォークスルーのタイトルボタンもあります ラーニングセンターではウォークスルーは 他のバイトバディである Expertの画像ボタンです
これをタップすると いくつか操作が実行されます 最初にラーニングセンターが 再びプレビューに替わります 次に 開いていない場合は タスクのfile引数で指定された ファイルがソースエディタで開きます 3つ目にソースエディタの上に タスクビューが表示されます 最後にコードウォークスルー コメントでマークされた コードがソースエディタで強調されます コンテンツが画面に表示されていないと 強調が必要な行までスクロールします Swift Playgroundsで ウォークスルーを書く方法で 複数のページを持つウォークスルーがどうか おそらく気になると思います Xcodeでプロジェクトを開き残りを完成させます
Xcodeでガイドファイルを開いて ウォークスルーにページを追加します ビュー修飾子について少し説明しましたが カスタムビュー修飾子を作る 方法を詳しく説明します 先にページを追加します
素晴らしい カスタムビュー修飾子の ウォークスルーができました
ViewModifierプロトコルの 説明もして良いと思います これで必要に応じて独自の ViewModifiersを作れます タスクグループに別の ウォークスルーを追加します
これで2つのウォークスルーを全て紹介しました iPadに切り替えてどう見えるか確認します
プロジェクトを開くと ラーニングセンターに2つの ウォークスルーがあります 最初のほうをタップします
前と同様 ビュー修飾子を持つ行が強調され タスクがドロップダウンし このコードが何かを示します これで 次のボタンをタップできます
ソースエディタが下の修飾子構造体に移動し これについて説明します
次へ を再びタップすると 最終ページに移動します ここでは修飾子構造体内の メソッドの詳細を説明します 下にウォークスルーというボタンが表示され
タップするとタスクが自動的に開始されます この機能は別のタスクが発達する限り 指導システムにより無料で提供されます ここで ウォークスルーの 残りの部分をタップします
Swift Playgroundsで作成する方法もあります 次に学習者がコードを追加し 何が起こるか確認できるよう 別の種類のタスクを作成する方法を説明します 現時点でよいパーティーをしています 創造動物は踊っていて背景には光があります ナイトクラブのように見えます もう少し良くできると思います 創造動物に色を加えると素敵だと思います 小さなクラブのライトの下で 踊っているようです 私のだけですあなたはどうしますか? ここに 実験タスクへの入口 が表示されます 実験は学習者が興味を持っていたり Appを独自のものにしたい場合に 追加できるオプションのコードです ガイドファイルに戻り すでに作業したステップに 実験タスクを追加できます 「実験」という名前の新しい 「実験」という名前の新しい サブタイトルと実験タスクの始まりを 入力しました
実験タスクとウォークスルーの違いは type引数の入力するものです 他はウォークスルータスクと 同じ規則に従います ページディレクティブは それと同様に機能します 実験では1つのオプション引数 isAdableだけを追加します isAdable引数の使用で実験タスクでコードを ソースエディタに直接追加できます isAdableが正確に設定されている場合 ボタンが コードスニペット横の 学習タスクに表示されます トリプルバックティック マークダウン構文を使って ページディレクティブ内に コードブロックを包みます コードブロックは10行以下に することをお勧めします スクロールの必要がない場合 必要であればタスクに より長いコードスニペットを表示できます コードがPlaygroundsに どう表示されるか確認します isAdable引数が適正に設定されているため コードスニペットの右側に 追加ボタンがあります これが 実験タスクを書くのに 必要なほぼすべてです isAdable引数を覚えていますか? 実験タスクでソースエディタ にコードを追加できますが スニペット追加場所を指定する必要があります クリーチャーダンスSwiftに戻ります 不透明度修飾子のすぐ下に 色修飾子を追加します ここで実験タスクコメントを追加します 実験タスクコメントは1行で ダブルスラッシュで始まり 次にダッシュ ラーニング ダッシュ タスクを記述します 次に括弧がきて 中に実験タスクのIDを記述します 実験タスクをテストするのに 必要なもの全てです Stephanieと私はもう一度 既に書いた swiftpmプロジェクトに取り組んでいます ちょっと見てみましょう 再びラーニングセンターに戻ります 今回 最初の実験を行う ボトムタスクのグループに 焦点を当てたいと思います 実験結果は 他のバイトバディブルーによって 教育システムに記録されています 実験タスクをタップしてみましょう
次に起こることは見覚えがあるでしょう タスクビューがドロップダウンします この時点ではタスクビューに コードビューが含まれます コードビューの右側に追加ボタンがあり タップしてソースエディタに コード権限が追加されます
コードが追加されたので クリーチャーダンスビューの変更を確認します パーティーを始めましょう!
かわいい 創造動物に当たっている 光を確認することができます これだけで素晴らしいですが もう一段階タイマーを使って 数秒毎に不規則に色を変えることもできます それには別の実験を追加する必要があります それではこれをXcodeに戻し 新しいタスクを追加します 2つ目の実験に追加する前に 既存の実験にページを 追加することをお勧めします 学習者が一連のコードを追加するのは複雑で その理由や機能がわからない場合があります そのためコードページの前に テキストページを追加します
これで2つ目のタスク追加の準備ができました 再び学習者のプロジェクトに コードを追加してほしいので 説明ページを追加後に コードスニペットを加えます
カスタムビュー修飾子を使い できることについて 学習者に教えるため新しい コンテンツが作られました 作ったものを見せる準備はいい? ええ やってみましょう
iPadでコンテンツの最終版を開き 私とMarcusの変更が どう結合するか確認します 最初にプロジェクトを開くと ウェルカムメッセージがでて 創造動物パーティーが紹介されます ウェルカムメッセージの詳細をタップすると ラーニングセンターが開きます すごい ラーニングセンターの上部に私の説明があり Marcusは4つのタスクを追加しました 最初のウォークスルーをタップしてみましょう
Animated Scaling修飾子をMarcusは例に使い カスタムビュー修飾子の使い方を説明しました
次のボタンをタップすると2つ目が表示されます
ビュー修飾子のプロトコルを 例に使い動作を説明しました 第2のウォークスルーが終わり 完了をタップすると 最初の実験タスクに移行されます
ストロボライトのダンスタスクでは colorMultiply修飾子を含む コードスニペットの追加で 創造動物に色を加えることが できるとわかります コードスニペットが追加される前の ダンスパーティーがどうか 思い出してみましょう
確かに クールだ 追加をタップしてコードスニペットを追加し パーティー開始を再び タップし変更を確認します
創造動物が素敵な色に変わりました 実験タスクを終了し最後のタスクに移行します
実験切り替えタスクでは ジェスチャーとタイマーで 創造動物の色をカスタマイズできます コードスニペットを追加し 再びパーティーを始めます
動物をタップすると色が変わります 素晴らしい 最後のタスクを完了して ラーニングセンターヘ戻って
これで すべてのタスクが 「完了」と表示されました つまりサンプルが完成しました
Swift Playgrounds 4で新しいコンテンツ機能を 活用する方法を紹介しました 今日のセッションが楽しめたらよかったです どんな学習体験を構築するか 楽しみにしています Swift Playgroundsセッション を忘れずにチェックし 最初のAppを構築してください 他のWWDCもお楽しみください では 失礼します これからパーティーなので
-
-
1:27 - Dance Floor
let numOfTiles = 100 let squareLength = 150.0 // Dance floor ForEach(0 ..< numOfTiles, id: \.self) { index in let i: CGFloat = CGFloat(index / 10) let j: CGFloat = CGFloat(index % 10) let x = (squareLength * i) - (squareLength) let y = (squareLength * j) - (squareLength * 2) Rectangle() .frame(width: squareLength, height: squareLength) .border(.black, width: 3) .position(x: x, y: y) .randomizedColorEffect(startAnimation: startParty) } .blur(radius: 15) .opacity(startParty ? 1.0 : 0.0)
-
1:47 - Dance
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() .animatedScalingEffect(startAnimation: startParty) .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1.0 : 0.0) }
-
2:08 - Disco Ball
Text("🪩") .resizableFont() .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1 : 0)
-
5:12 - Guidebook Directive
@GuideBook(title: "Creature Party!", icon: icon.png, background: background.png, firstFile: CreatureDance.swift) { }
-
5:28 - Welcome Message
@WelcomeMessage(title: "Welcome to Creature Party!") { In Creature Party, you'll take this app of dancing creatures to the next level with the help of colors, shapes, animations, and plenty of emoji! }
-
5:37 - Guide and Step Directives
@Guide { @Step(title: "Pump up the jams") { } } }
-
5:53 - Content and Media Directive
@ContentAndMedia { Tonight, the creatures are gonna party like it's 2022. 🐙💃🦝🕺🦦 }
-
7:15 - Task Group Directive
@TaskGroup(title: "Walkthroughs") { Here are the walkthroughs! These will help explain all of the new code. }
-
7:57 - First Walkthrough Task
@Task(type: walkthrough, id: "partyMode", title: "Setting up the Party", file: CreatureDance.swift) { }
-
8:44 - First Walkthrough Page
@Page(id: "1.modifier", title: "") { This is a [view modifier](https://developer.apple.com/documentation/swiftui/viewmodifier). Modifiers let you create unique versions of a view in SwiftUI. }
-
9:48 - Walkthrough Highlight
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() /*#-code-walkthrough(1.modifier)*/ .animatedScalingEffect(startAnimation: startParty) /*#-code-walkthrough(1.modifier)*/ .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) .animatedRotationEffect(startAnimation: startParty) .opacity(startParty ? 1.0 : 0.0) }
-
11:56 - First Walkthrough extra pages
@Page(id: "1.struct", title: "") { Custom view modifiers are structures that contain code for explaining how to modify whatever view the given modifier is attached to. } @Page(id: "1.body", title: "") { The body method allows you to add custom view modifications. For example, here you're adding a scaling animation that grows and shrinks the `Creature` over a certain period of time. }
-
12:18 - Second Walkthrough Task
@Task(type: walkthrough, id: "protocol", title: "A Little More on Protocols", file: CreatureDance.swift) { @Page(id: "2.protocol", title: "") { All custom view modifiers implement the `ViewModifier` protocol. } @Page(id: "2.body", title: "") { The `ViewModifier` protocol requires all structures that implement it to write the `body(content:)` method. } @Page(id: "2.usage", title: "") { After you've written content for your `body(content:)` method, you can use it on any view you want. Here you'll use it on each `Creature` to add a rotation animation. } }
-
14:21 - First Experiment Task
@TaskGroup(title: "Experiments") { Time to set this party off! You can use experiments to add some extra pazazz to the dance floor. @Task(type: experiment, id: "colors", title: "Dancing in the Strobe Light", file: CreatureDance.swift) { } }
-
14:48 - First Experiment Page
@Page(id: "3.code", title: "", isAddable: true) { ``` .colorMultiply(creatureColor) ``` }
-
15:55 - Experiment Task Comment
ForEach(data.creatures) { creature in Text(creature.emoji) .resizableFont() /*#-code-walkthrough(1.modifier)*/ .animatedScalingEffect(startAnimation: startParty) /*#-code-walkthrough(1.modifier)*/ .randomizedOffsetEffect(startAnimation: startParty, x: midX * 0.6, y: midY * 0.6) /*#-code-walkthrough(2.usage)*/ .animatedRotationEffect(startAnimation: startParty) /*#-code-walkthrough(2.usage)*/ .opacity(startParty ? 1.0 : 0.0) //#-learning-task(colors) }
-
17:42 - Experiment Text
@Page(id: "3.lights", title: "") { Next, add some colors to the creatures so it looks like they're dancing under the lights! }
-
17:55 - Second Experiment Task
@Task(type: experiment, id: "timer", title: "Switch it Up", file: CreatureDance.swift) { @Page(id: "4.lights", title: "") { Now that you have some colors, you can add some code to change the color of the creatures using a timer. Let's add one! } @Page(id: "4.code", title: "", isAddable: true) { ``` .onTapGesture { if let timer = timer { timer.invalidate() self.timer = nil } else { creatureColor = Color.randomColor timer = Timer.scheduledTimer(withTimeInterval: 2.0, repeats: true, block: { timer in creatureColor = Color.randomColor }) } } ``` } }
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。