ハイライト
TipKit を使用すると、数行のコードだけでアプリ関数プロンプトの作成、表示制御、正確な配置が可能になります。パラメーター ルールとイベント ルールの組み合わせをサポートし、ターゲット ユーザーをターゲットにし、教育情報が嫌がらせのポップアップに変わるのを防ぎます。
主要内容
アプリには優れた機能があるのに、ユーザーがそれを見つけることができません。これは、すべての開発者が遭遇するジレンマです。従来のアプローチでは、最初の起動時に長い紹介ページを作成します。ユーザーはすぐに読み飛ばしてしまうか、読んだ後に忘れてしまいます。
TipKit には異なるアイデアがあります。つまり、適切なタイミングで適切な人に適切なチップを提示するというものです。 iPhone、iPad、Mac、Apple Watch、Apple TV をカバーしており、一連の API はすべてのプラットフォームに共通です。
プロンプトの作成
プロンプトはタイトルとメッセージで構成されます。タイトルには、「お気に入りの裏庭を集めてください」など、直接的なアクションのフレーズを使用します。 「お気に入りのバックヤードがリストの先頭に表示されます。」などのメリットを説明するメッセージが表示されます。 (01:53)
ヒントにはアイコン(SFシンボル)やアクションボタンを付けることができます。アイコンはユーザーが視覚的なつながりを作るのに役立ち、アクション ボタンは設定ページやガイド プロセスにジャンプできます。
ただし、すべてのシナリオが TipKit に適しているわけではありません。広告のセールストーク、エラーメッセージ、機能アップデートの通知、複雑な複数ステップの指示などは、ユーザー教育の例ではありません。 (02:25)
2つの表示方法
ポップオーバー: 現在のページ レイアウトを変更せずに特定の UI 要素をポイントするフローティング レイヤー フォーム。ユーザーにボタンをクリックするよう誘導するのに適しています。 tvOS はこの方法のみをサポートします。 (04:15)
インライン: インライン モードでは、アプリ UI が自動的にスペースを確保し、コンテンツをブロックしません。リストまたはフォームにプロンプトを表示するのに適しています。
ルールシステム
ルールは TipKit の中核機能であり、最も必要な人にのみヒントが表示されるようにします。 (06:02)
パラメータベース: Swift 値タイプに基づく永続的な状態。たとえば、ユーザーがログインしているかどうか、または特定の設定がオンになっているかどうかなどです。
イベントベース: ユーザーの行動カウントに基づきます。たとえば、「詳細ページに 3 回アクセスするとプロンプトが表示されます。」イベントには、時間範囲 (「過去 5 日間に 3 回訪問」) とカスタム相関タイプ (「同じ裏庭を 3 回訪問」) を指定できます。
ルールは組み合わせることができます。たとえば、「ログイン + 過去 5 日間に詳細ページに 3 回アクセス + バックヤードをお気に入りに登録したことがない」 - このプロンプトは、3 つの条件がすべて同時に満たされた場合にのみ表示されます。
表示制御
複数のプロンプトが同時に存在する場合、ユーザーを圧倒しないように表示リズムを制御する必要があります。 (09:57)
TipsCenterグローバルな表示頻度制御を提供します。
.daily: 1 日に最大 1 つのヒントを表示します -.hourly:1時間に最大1回表示 -.immediate:条件を満たすとすぐに表示、回数制限なし- カスタマイズ
TimeInterval:例えば5日に1回
個別のプロンプトを設定可能.ignoresDisplayFrequency(true)グローバルな周波数制限をスキップします。特に重要な機能のガイダンスに適しています。設定することもできます.maxDisplayCount(5)インプレッションの総数を制限します。これを超えると自動的に期限切れになります。
プロンプトを削除する方法もいくつかあります。ユーザーはプロンプトに記載されている操作を実行します (呼び出しinvalidate(reason: .userPerformedAction))、インプレッションの最大数に達した場合、または開発者が任意の条件に基づいて呼び出した場合invalidate()。(11:27)
### テスト
TipKit は完全なテスト API を提供しており、ルールを満たさなくてもプロンプトの効果を確認できます: (12:46)
TipsCenter.showAllTips(): すべてのヒントを表示 -TipsCenter.showTips([tip1, tip2]): 指定されたプロンプトのみを表示します -TipsCenter.hideAllTips():すべてのプロンプトを非表示にする -TipsCenter.resetDatastore(): すべてのTipKitデータをクリアします
これらは、迅速なテストを容易にするために、Xcode Scheme の Launch Arguments を通じて構成することもできます。
詳細
基本的なプロンプト定義
import TipKit
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.")
}
}
キーポイント:
- に従う
Tip合意は少なくとも履行されているtitleそしてmessage titleそしてmessage戻るTextタイプ、SwiftUI 修飾子をサポート- プロンプト定義は値型であり、インスタンスをグローバルに作成することで再利用できます。
アイコンとアクションを含むプロンプト
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"
)
]
}
}
キーポイント:
assetSF シンボルまたはカスタム画像を使用して、ユーザーが視覚的な関連付けを確立できるようにします -actions配列はボタンを定義し、各アクションには一意の ID とタイトルがあります -で.popoverMiniTipコールバック内のアクション ID によるクリックの処理
初期設定
@main
struct BackyardBirdsApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
init() {
TipsCenter.shared.configure()
}
}
キーポイント:
TipsCenter.shared.configure()アプリの起動時に呼び出す必要がある- プロンプトステータスとイベントデータの永続化を担当します。 ・呼び出されなかった場合、アプリ再起動後、イベント数やプロンプトの表示状態は保持されません。
ポップオーバー表示
private let favoriteBackyardTip = FavoriteBackyardTip()
// ...
.toolbar {
ToolbarItem {
Button {
backyard.isFavorite.toggle()
} label: {
Label("Favorite", systemImage: "star")
.symbolVariant(
backyard.isFavorite ? .fill : .none
)
}
.popoverMiniTip(tip: favoriteBackyardTip)
}
}
キーポイント:
.popoverMiniTip(tip:)これは、プロンプト フローティング レイヤーをターゲット ビューに自動的にアタッチする SwiftUI モディファイアです。- ヒントは、モディファイアが配置されているビュー要素を自動的に指します。
- ヒントの表示/非表示はルールに従ってTipKitによって自動的に管理され、手動制御は必要ありません
パラメータのルール
struct FavoriteBackyardTip: Tip {
@Parameter
static var isLoggedIn: Bool = false
var rules: Predicate<RuleInput...> {
#Rule(Self.$isLoggedIn) { $0 == true }
}
}
キーポイント:
@Parameterタグの静的プロパティは永続的で、値はアプリの再起動後も保持されます。- ログイン成功後に設定
FavoriteBackyardTip.isLoggedIn = true #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...> {
#Rule(Self.$isLoggedIn) { $0 == true }
#Rule(Self.enteredBackyardDetailView) { $0.count >= 3 }
}
}
// 在视图中捐赠事件
.onAppear {
FavoriteBackyardTip.enteredBackyardDetailView.donate()
}
キーポイント:
Event定義には一意の ID が必要であり、関連するタイプに関連付けることができます。DonationValue.donate()イベントが発生すると呼び出され、TipKit は自動的にタイムスタンプを記録します -$0.countこのイベントの寄付の合計数を返します- 複数
#Ruleデフォルトは AND 関係であり、すべて満たされる必要があります。
時間フィルターを使用したイベント ルール
#Rule(Self.enteredBackyardDetailView) {
$0.donations.filter {
$0.date > Date.now.addingTimeInterval(-5 * 60 * 60 * 24)
}
.count >= 3
}
キーポイント:
$0.donationsを含むすべての寄付記録を返します。dateおよび関連データ- 使用する
filter時間範囲内のレコードをフィルタリングする - 時間計算用
addingTimeInterval、単位は秒です
関連するタイプを持つイベント ルール
extension FavoriteBackyardTip {
struct DetailViewDonation: DonationValue {
let backyardID: Int
}
}
// 捐赠时附带数据
.onAppear {
FavoriteBackyardTip.enteredBackyardDetailView.donate(
with: .init(backyardID: backyard.id)
)
}
// 规则中按 backyardID 分组统计
#Rule(Self.enteredBackyardDetailView) {
$0.donations.filter {
$0.date > Date.now.addingTimeInterval(-5 * 60 * 60 * 24)
}
.largestSubset(by: \.backyardID)
.count >= 3
}
キーポイント:
- アソシエーションタイプのコンプライアンス
DonationValueプロトコル、シリアル化可能なデータを保存可能 -.largestSubset(by:)指定された属性でグループ化し、最大のグループ内のレコード数を返します。 - この例は、「過去 5 日間に同じバックヤード詳細ページに少なくとも 3 回アクセスした」ことを意味します。
- 関連するデータが小さいほど、クエリは高速になります。完全なオブジェクトではなく、ID のみを保存することをお勧めします。
表示周波数設定
// 全局频率:每天一个提示
TipsCenter.shared.configure {
DisplayFrequency(.daily)
}
// 单个提示跳过频率限制
struct FavoriteBackyardTip: Tip {
var options: [Option] {
[.ignoresDisplayFrequency(true)]
}
}
// 单个提示最多展示 5 次
struct FavoriteBackyardTip: Tip {
var options: [Option] {
[.maxDisplayCount(5)]
}
}
キーポイント:
- グローバル周波数は次のとおりです。
TipsCenterレベル構成、すべてのプロンプトに影響します -.ignoresDisplayFrequency個々のプロンプトをグローバルな制限から独立させる -.maxDisplayCountプロンプトの合計インプレッション数を制限します。この数に達すると、自動的に期限切れになります。
プロンプトが無効です
Button {
backyard.isFavorite.toggle()
favoriteBackyardTip.invalidate(reason: .userPerformedAction)
} label: {
Label("Favorite", systemImage: "star")
.symbolVariant(backyard.isFavorite ? .fill : .none
}
.popoverMiniTip(tip: favoriteBackyardTip)
キーポイント:
.userPerformedActionユーザーがプロンプトに記載されている操作を実行したことを示します- 電話する
invalidate()プロンプトはすぐに消え、再度表示されることはありません。 - も使用できます
.tipClosedユーザーが手動で閉じたか、理由をカスタマイズしたことを示します
重要ポイント
1.段階的機能ガイダンスシステム やるべきこと: 新規ユーザーが一度にすべての情報を詰め込むのではなく、順番に機能を発見できるように、アプリのコア機能を段階的にリマインダーするシステムを設計します。 実行する価値がある理由: TipKit のルール システムにより、「適切なタイミングで適切なヒントを表示する」ことがプログラム可能になり、ユーザー エクスペリエンスが従来のランディング ページよりもはるかに優れています。 開始方法: アプリの主要な機能を 5 ~ 10 個リストし、各機能のヒントを作成し、イベント ルールを設定します (例: 「機能 A を 3 回使用した後に機能 B を要求する」)。
2.インテリジェントなユーザー階層化 対処方法: ユーザーの行動データに基づいて、イベント ルールを使用して初心者、一般ユーザー、上級ユーザーを自動的に区別し、異なるプロンプトを表示します。 実行する価値がある理由: 同じヒントは初心者には役立ちますが、経験豊富なユーザーにとっては迷惑です。 TipKit のカスタム寄付タイプにより、きめ細かな階層化が可能になります。 開始方法: ユーザー行動イベント (「最初のプロジェクトの作成」、「高度な機能 X の使用」など) を定義し、行動の詳細を関連付けタイプとともに記録し、それらをルールに組み合わせてユーザーの段階を決定します。
3.クロスデバイスプロンプト同期 対処法: TipKit の iCloud 同期機能を活用して、ユーザーが iPhone で閲覧したヒントが iPad で二度表示されないようにします。 実行する価値がある理由: マルチデバイス ユーザーがますます増えているため、教育を繰り返すと製品の品質が低下します。 開始方法: TipKit はデフォルトで iCloud 同期をオンにし、追加のコードは必要ありません。プロンプト ID がプラットフォーム間で一貫していることを確認してください。
4. A/B テストのプロンプト コピー
対策: 同じ機能に対してプロンプト コピーライティングのセットを複数用意し、イベント ルールで表示率を制御し、コンバージョン率データを使用してどのセットがより効果的かを検証します。
実行する価値がある理由: プロンプトのタイトルとメッセージは、ユーザーが新しい機能を試すかどうかに直接影響し、コピーライティングの最適化には明確な ROI があります。
開始方法: 2 種類のチップを作成します (例:FavoriteTipVariantAそしてFavoriteTipVariantB)、パラメータルールを使用して表示率を制御し、クリック率やアクションボタンの機能使用率を通じて効果を評価します。
関連セッション
- アプリのショートカットのデザイン — アプリのショートカットのビジュアル言語デザイン ガイド。TipKit と同じユーザー検出システムに属します。
- 動的なライブ アクティビティの設計 — リアルタイム アクティビティの設計原則、システム レベルでアプリ情報を表示する方法を学びます
- 空間コンピューティングのための SwiftUI を紹介 — 空間コンピューティングにおける SwiftUI の新機能、TipKit はvisionOSもサポート
コメント
GitHub Issues · utterances