ストリーミングはほとんどのブラウザと
Developerアプリで視聴できます。
-
TipKitによって機能を見つけやすくする方法
TipKitを使ってアプリの使い方について伝えるようにしましょう!ヒントを通じて効果的かつ教育的な瞬間をどのように作ることができるかについてご確認ください。理想的なオーディエンスに到達するための適格性ルールを構築する方法、ヒントの頻度をコントロールする方法、成功するインタラクションを確実にするためのテスト戦略について解説します
関連する章
- 0:00 - Intro
- 1:27 - Create a tip
- 5:23 - Eligibility rules
- 9:19 - Display and dismissal
- 12:35 - Test tips
- 13:56 - Wrap-up
リソース
関連ビデオ
WWDC24
-
ダウンロード
♪ ♪
こんにちは Instructional Design マネージャーのEllieです TipKitを使って機能を見つけやすく することについてお話します 最初のヒントを作成する方法 ヒントが表示される人を 指定するためのルール アプリ内での教育に役立つメッセージの 表示や非表示のタイミングや 頻度などを制御し ヒントをテストする方法を確認します その前にTipKitの背景について
人々が気に入るとわかっている機能に 取り組まれているかと思います ですがまずはその機能を発見してもらう 必要があります TipKitは アプリにヒントを簡単に 表示できる新しいフレームワークです
Appleのすべてのユーザー教育に 携わるInstructional Products Teamとして 特に教育に役立つことを念頭に置いて TipKitをデザインしました TipKitは他の人に新しい 機能について教えたり 隠れた機能の発見を 手伝ったりすることができます あるいはより速くタスクを達成するやり方を 教えてあげることもできます iPhone iPad Mac Apple Watch Apple TVで 利用可能です それではヒントの作成に取りかかります 裏庭をお気に入り登録する 機能があります お気に入りに登録するとその人が 最も気になる裏庭に 簡単にアクセスできます そのためヒントの候補として最適です 一旦機能を特定したら Xcodeにアクセスする準備ができました まず「裏庭をお気に入り登録」に 関する新しいヒントを定義します ヒントはタイトルとメッセージで 構成されています 役に立つヒントにはその機能が 何であるかを示すタイトルとしての 直接的なアクションフレーズと 覚えやすい利益となる情報や 説明のメッセージがあり ユーザーはなぜその機能を 使いたいのかを知ることができます
効果的なヒントの例をいくつか紹介 してみましょう これらはすべて実践可能であり 指導的で 覚えやすいものになっています こちらはTipKitを使用すべきでない場合の いくつかの例です 1つ目はプロモーションで もうひとつはエラーメッセージで どちらも教育に役立つものではありません 3つ目は機能が向上するのは 素晴らしいことですが それを利用する人は 何もする必要がありません 最後のは便利だが複雑すぎて その場で読んで覚えるには
あまりに複雑です ヒントに戻りましょう タイトルとメッセージはすでに用意しました 次にヒントのビューの基本構造にそれらを加え TipsCenter を設定します TipsCenter はTipKit の主要な機能を実現し ヒントと関連イベントを アプリの起動を跨いで持続させ テストを容易にします TipsCenterのデフォルトの共有 インスタンスが提供されているので
それを追加しTipsCenterが構成されたので ヒントが見れるようになりました いい感じだけどもっとよく見えるはずです テキストの色をアプリに合うように 藍色に変更し アイコンを入れて注意を 引きやすくしてみます 星マークを選んだのは お気に入り登録 についてのヒントだからです 機能に対して カスタマイズ可能な設定がある場合は アクションボタンを追加してください アクションボタンは 人々が素早く 調整できるようにそれらの設定に 直接移動することができます あるいは特に役に立つと思われる 情報があれば オンボーディングフローなどの 追加リソースにリンクもできます OK うまくいったようです 次に最適な配置を見極めてみます ヒントのビューには2種類あります: 1つ目はポップオーバービューです アプリのUIの上にヒントを表示できます 現在のアプリ画面を変更することなく ボタンやその他の要素を 直接指すことができます tvOSでは主にポップオーバー ビューが使われます もうひとつはインラインビューで これはアプリの UIを一時的に調整する形になります そのためUIがブロックされることは ありません どちらのビューを使用する場合でも 呼び出す関連ボタンや 要素の近くに ヒントが表示されるようにすると便利です 裏庭をお気に入りに入れるには ポップオーバービューを使い 右上に配置されているスターボタンを ポイントするように配置します これが私のアプリの最初のヒントに なりました 素晴らしい出来栄えで 文脈にも合っています しかしベストなタイミングで理想的な オーディエンスに リーチするというTipKitのパワーを 本当に活用するためには いくつかのルールを追加したいと思います Charlieに次のレベルへの ヒントについて話してもらいましょう Charlie: ありがとう Ellie Instructional Products teamのソフトウェア エンジニアリングマネージャーの Charlie Parksです 新しい機能を発見することは 驚きと喜びを呼び起こしますが その機能がその人にとって 興味深いものであり それに関して伝えることがスパム的ではなく 無関係ではない場合に限られます 裏庭のお気に入り登録についての ヒントは役に立つでしょうが 特にその機能を知っている人には 向かないかもしれません アプリをあまり使用しない人の 関心も低いかもしれません Appleではアプリ内での教育はその 恩恵を受ける人に焦点を当てるべきだと 考えていて アプリ内で何かを 達成しようとしている人の 邪魔にならないようにすることを 目標にしています 最も適切なオーディエンスに 最も適したタイミングで 確実にヒントを表示します TipKitは単独または組み合わせて 使用することができる 適格性に関する多くのルールが 用意されています ルールには主に2つのタイプがあり 1つ目はパラメータベースのルールで パラメータベースのルールは 永続的でSwiftの値型に基づいた ヒントを表示するのに適しています もうひとつはイベントベースのルールです イベントベースのルールでは ある人がヒントの対象となる前に 実行しなければならないアクションを 定義することができます
裏庭のお気に入り登録のヒントのために まず最初にしたいことは アカウントにログインしていることを 確実にすることです パラメータベースのルールを実装します まずパラメーターの初期値を falseに設定します そしてヒントのルールにこれを付け加えます いいですね ヒントをもらう人を絞れましたが さらに絞ってみたいです 人々がアプリを使い当たり前のように その機能を 見つけられるようにしたいです その方法とは次のようなもので イベントベースのルールを 作成することです 詳細ビューに3回以上 アクセスした後だけに表示されるよう
まずイベントを作成します このルールがtrueと評価されるまでに イベントを誘発させたい回数を カウントします 今回ヒントを提示する前に 裏庭の詳細ビューに3回 アクセスしてもらいたいです 最後に必要なのはイベントを 報告することです 裏庭詳細ビューでは ビューが表示されるたびに イベントを報告します ルールがまとまりつつありますが もう少し強化したいとしたらどうでしょう? 裏庭の詳細ビューを 頻繁に見にくる人にも関わらず お気に入り登録していない人たちに 焦点を絞ってきましたね さらにアプリを定期的に 使用している人だけに表示したいと 考えました
イベントベースのルールに日付クエリ モディファイアを追加して過去5日間に3回 裏庭の詳細ビューにアクセスした場合のみ trueと評価されるようにします TipKitのもう一つの強力な機能は 各イベントに関連するタイプを追加して カスタムドネーションを作成する機能です 関連タイプを使用すると イベントベースのルールをさらに 絞り込むことができ誰かが特定の 裏庭詳細ビューに移動した
場合にのみマッチします まずDetailViewDonationを作成し 特定の裏庭ビューのIDを指定します そして私のドネーションで 裏庭ビューのIDを記載します この2つが確立したら 固有の裏庭IDに基づいて イベントを照会するルールに 更新します これらのカスタムドネーションを 定義する際には 保存されるデータのサイズに 留意してください サイズが大きいほどクエリの実行速度は 遅くなりクエリの実行速度が低下します TipKitのルールでは 簡単に強力なものを作成できます ヒントを最も恩恵を受ける人たちに 表示するための強力でシンプルな方法を 提供しルールは一般的なものから 具体的なものまで 必要に応じて 組み合わせることができます アプリにヒントが表示されたら いつまでも画面に表示させたくないですし その人がヒントに書かれている機能を 使った場合にヒントを長引かせたままに したくありません 複数のヒントがある場合 圧倒されかねないですし やろうとすることの 邪魔になりかねないので 一度に全部を表示させないように したいものです TipKit はいくつかの表示および非表示 ビヘイビアを提供します ヒントは適切な間隔で表示され 有益である限り表示されます 例えばさらにいくつかのヒントを アプリに追加したとしましょう Backyard Birdsアプリに 5つのヒントを加えました ヒントはどれも役に立つものですが 一度にすべて表示された場合は 効果的ではなくなってしまいます TipKitではヒントの表示頻度を設定でき より理想的なケイデンスで表示できます
TipCenterでは別のヒントが 表示されるまでの時間を 指定することができます 24時間ごとに表示させたい場合は .dailyを 60分ごとに表示させたい場合は .hourlyを使うことができます 有効な時間間隔の値を指定することで カスタム期間を指定することもできます また本当に即座に教育が必要ならば .immediateモディファイアを 使うこともできます このようにすると 最近別のヒントが表示されたとしても その瞬間に自分が対象となる ヒントが表示されます 表示頻度を無視する代わりに TipsCenterレベルで 1回限りのヒント単位で 無視する方が便利かもしれません そのために .ignoresDisplayFrequencyオプションを 追加します これでその特定のヒントだけが 誰かが対象となる瞬間に表示され 一方でアプリの残りのヒントは TipsCenterレベルで設定した 表示ケーデンスに従います ヒントが表示されたら有益な限り 画面上に表示されるようにしたいです ですから もし誰かが ヒントに書かれている機能を使用し アクションを実行した場合 または ヒントの対象ではあるが まだそのヒントに興味がない場合 そのヒントは非表示にするべきです アプリを使う人がヒントを表示させるための ルールをすべて満たしているとしましょう ログインしており過去5日間に3回 裏庭の詳細ビューを開いているが どの裏庭でもお気に入りボタンを タップしたことがなかったとします その人がヒントを見て お気に入りボタンをタップしたら 「.userPerformedAction 」 という理由で 無効化メソッドを 呼び出します もう一つの非表示方法は 定義された.maxDisplayCountより 多く表示された場合です この場合ヒントが5回表示され 何もアクションを起こさなければ 次に裏庭詳細ビューに 入ったときに 表示されることはありません これらはTipKitが提供する 組み込み機能を使用して ヒントを非表示にする方法の一部です しかしアプリのことを 一番よく知っているのは みなさんですので .invalidate()メソッドを 使うことでどんなインタラクションや 基準にもとづいても ヒントを非表示にすることができます TipKitはiCloud経由でヒントの ステータスを同期することもできます 例えばそのアプリをiPadとiPhoneの 両方にインストールして使っている人がいて その機能性がどちらのデバイスでも 同じである場合 おそらく両方のデバイスで機能について 教育しない方がよいでしょう それではEllieに TipKitが提供するAPIのテストと 次のステップについて 話てもらいます Ellie: テストを簡単にするために TipKit には必要に応じて ヒントを表示したり非表示にしたり 適格性ルールを回避するために使用できる 便利な API が付いています アプリ内のすべてのヒントを 設定されたルールを満たしていなくても 検査することができます そのためにはTipsCenterの設定に .showAllTips を追加します テスト時に特定のヒントだけを表示 したい場合は.showTips を使用し 特定のヒントのIDを渡すか .hideTipsを使用して 特定のヒントを表示しないようにします アプリの別の機能に集中するために ヒントを表示しないようにしたい場合は .hideAllTipsを 使用します .resetDatastoreを使用して アプリを ビルドするごとに元の状態を設定し TipKitデータストア内のすべての情報を 消去することもできます API経由で呼び出すことができる テストオプションはすべて 起動時の引数としても利用できます これらのいずれかを使用して簡単な スポットチェックや全機能のテストに 利用できます これで準備完了です ヒントを作成しルールを追加しました アプリでヒントの頻度を設定し 現在テストをしています まとめると ヒントはアプリの機能を 発見してもらうのに最適です ヒントは短くまとめること 理想的なオーディエンスに届けるために 簡単に定義できる強力なルールのもとに ターゲットしましょう TipKitのサンプルコードは developer.apple.comで 公開されます さらなる詳細については TipKitのヒューマンインターフェイス ガイドラインをご確認ください TipKitを念頭に置いてアプリを見直して 新機能の開発に 取り組んでいただければと思います Instructional Products Teamを代表して ご視聴ありがとうございました
-
-
1:55 - Create a tip
struct FavoriteBackyardTip: Tip { var title: Text { Text("Save as a Favorite") } var message: Text { Text("Your favorite backyards always appear at the top of the list.") } }
-
2:48 - Configure TipsCenter
@main struct BackyardBirdsApp: App { var body: some Scene { WindowGroup { ContentView() } } // ... init() { TipsCenter.shared.configure() } }
-
3:18 - Add actions and an asset to a tip
struct FavoriteBackyardTip: Tip { var title: Text { Text("Save as a Favorite").foregroundColor(.indigo) } var message: Text { Text("Your favorite backyards always appear at the top of the list.") } var asset: Image { Image(systemName: "star") } var actions: [Action] { [ Tip.Action( id: "learn-more", title: "Learn More" ) ] } }
-
4:53 - Create a popover view
private let favoriteBackyardTip = FavoriteBackyardTip() // ... .toolbar { ToolbarItem { Button { backyard.isFavorite.toggle() } label: { Label("Favorite", systemImage: "star") .symbolVariant( backyard.isFavorite ? .fill : .none ) } .popoverMiniTip(tip: favoriteBackyardTip) } }
-
6:38 - Add a parameter based rule
struct FavoriteBackyardTip: Tip { @Parameter static var isLoggedIn: Bool = false // ... var rules: Predicate<RuleInput...> { // User is logged in #Rule(Self.$isLoggedIn) { $0 == true } } }
-
7:16 - Add an event based rule
struct FavoriteBackyardTip: Tip { @Parameter static var isLoggedIn: Bool = false static let enteredBackyardDetailView: Event = Event<DetailViewDonation>( id: "entered-backyard-detail-view" ) // ... var rules: Predicate<RuleInput...> { // User is logged in #Rule(Self.$isLoggedIn) { $0 == true } // User has entered any backyard detail view at least 3 times #Rule(Self.enteredBackyardDetailView) { $0.count >= 3 } } }
-
7:34 - Donate the event when a view appears
.onAppear { FavoriteBackyardTip.enteredBackyardDetailView.donate() }
-
7:59 - Filter event donations in an event based rule
// User has entered any backyard detail view at least 3 times in the past 5 days #Rule(Self.enteredBackyardDetailView) { $0.donations.filter { $0.date > Date.now.addingTimeInterval(-5 * 60 * 60 * 24) } .count >= 3 }
-
8:34 - Create a custom donation
// Create the associated type extension BackyardDetailTip { struct DetailViewDonation: DonationValue { let backyardID: Int } } // Donate the unique id of the backyard detail being viewed .onAppear { BackyardFavoriteTip.enteredBackyardDetailView.donate( with: .init(backyardID: backyard.id) ) } struct FavoriteBackyardTip: Tip { // ... var rules: Predicate<RuleInput...> { // Update the rule to specify a backyardID #Rule(Self.enteredBackyardDetailView) { $0.donations.filter { $0.date > Date.now.addingTimeInterval(-5 * 60 * 60 * 24) } .largestSubset(by: \.backyardID) .count >= 3 } } }
-
9:57 - Configure display frequency
// One tip per day. TipsCenter.shared.configure { DisplayFrequency(.daily) } // One tip per hour. TipsCenter.shared.configure { DisplayFrequency(.hourly) } // Custom configuration. Only show one tip every five days. let fiveDays: TimeInterval = 5 * 24 * 60 * 60 TipsCenter.shared.configure { DisplayFrequency(fiveDays) } // No frequency control. Show all tips as soon as eligible. TipsCenter.shared.configure { DisplayFrequency(.immediate) }
-
10:34 - Turn off display frequency controls for a tip
struct FavoriteBackyardTip: Tip { // ... var options: [Option] { [.ignoresDisplayFrequency(true)] } }
-
11:27 - Invalidate a tip
Button { backyard.isFavorite.toggle() // When user taps the favorite button, dismiss the tip favoriteBackyardTip.invalidate(reason: .userPerformedAction) } label: { Label("Favorite", systemImage: "star") .symbolVariant(backyard.isFavorite ? .fill : .none) } .popoverMiniTip(tip: favoriteBackyardTip)
-
11:41 - Configure max display count on a tip
struct FavoriteBackyardTip: Tip { // ... var options: [Option] { [.maxDisplayCount(5)] } }
-
12:46 - Programmatically call testing API
// Show all defined tips in the app TipsCenter.showAllTips() // Show some tips, but not all TipsCenter.showTips([tip1, tip2, tip3]) // Hide some tips, but not all TipsCenter.hideTips([tip1, tip2, tip3]) // Hide all tips defined in the app TipsCenter.hideAllTips() // Purge all TipKit related data TipsCenter.resetDatastore()
-
13:31 - Configure launch arguments in your scheme
// Show all defined tips in the app com.apple.TipKit.ShowAllTips 1 // Show some tips, but not all com.apple.TipKit.ShowTips tipID,otherTipID // Hide some tips, but not all com.apple.TipKit.HideAllTips 1 // Hide all tips defined in the app com.apple.TipKit.HideTips tipID,otherTipID // Purge all TipKit related data com.apple.TipKit.ResetDatastore 1
-
-
特定のトピックをお探しの場合は、上にトピックを入力すると、関連するトピックにすばやく移動できます。
クエリの送信中にエラーが発生しました。インターネット接続を確認して、もう一度お試しください。