Yappli Tech Blog

株式会社ヤプリの開発メンバーによるブログです。最新の技術情報からチーム・働き方に関するテーマまで、日々の熱い想いを持って発信していきます。

TipKitの活用を具体的に考えてみる

最近寒くてすっかり出不精な菅(@Nao_RandDです🫠

ヤプリでiOSエンジニアをしています

今回はヤプリのYappdateDayで取り組んだ「TipKitの活用検討」に関して紹介したいと思います

YappdateDayとは?

ヤプリにはバリューの一つに「再構築」を置いています

日々の改善を積み重ねプロダクトやサービスの進化に繋げよう、という思いが込められたバリューです

YappdateDayはまさにその「再構築」を表す取り組みの一つで、日頃の業務と止めて改善や進化に繋げることに集中できる日となっています

☟下記の記事☟で詳しく紹介されておりますので、ご興味ある方はぜひご覧になってみてください

tech.yappli.io


取り組んだこと

今回はTipKitはどんなものなのかと、どういった活用ができるのかを一緒に考えながら記事にしていきたいと思います

参考となるのはWWDC 2023の「Make features discoverable with TipKit」ですね

developer.apple.com

合わせてドキュメントも充実しており、必要なケースや実装サンプルもあります

developer.apple.com

TipKitの概要

まずは、TipKitについてざっくりと把握していきましょう

TipKitは、機能や情報をユーザーにヒントとして提示することができるフレームワークです

ユーザーがアプリの新機能や隠れた機能を発見するのをサポートしてくれる役割を果たしてくれます

[引用] Make features discoverable with TipKit

developer.apple.com

ヒントとして、アプリの機能やその利用に必要な情報を提供する目的で使用することが想定されています

エラーメッセージのダイアログ代わりに使用すること単なるプロモーションに使用すること非推奨とされています

Tipのタイプ

Tipのタイプは「ポップオーバータイプ」「インラインビュータイプ」の二つです(雑なスクショですみません!😇)

インラインビュータイプ ポップオーバービュータイプ

・UIに馴染む形で表示させることができる
・閉じた後のトルツメもよしなにしてくれる
・ユーザー操作を阻害しない

・ワイプのように表示させられる
・表示画面のどこかをタップで閉じられる
・UIをブロックさせてしまうため利用ケースには注意する

基本的な実装

TipKitでのTipは、Tipプロトコルに準拠させるだけで簡単に作成することができます

HogeTipというTipを作成する場合次のようなコードになります

import SwiftUI
import TipKit

// Tipの定義
struct HogeTip: Tip {
    var title: Text {
        Text("タイトル")
    }
    var message: Text? {
        Text("メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。メッセージ。")
    }
    var image: Image? {
        Image(systemName: "star")
    }
}

Tipを実際に表示させてみましょう

ここではインラインビューとして表示させてみます

struct HogeView: View {
    var tip = HogeTip()

    var body: some View {
        VStack(spacing: 20) {
            Text("TipKitを試してみたいと思います\n\n少ない実装で簡単にTipが表示できることがわかりますね!")

            // 下矢印を持つTipとして表示
            TipView(tip, arrowEdge: .bottom)
            Button {
                // Invalidate the tip when someone uses the feature.
                tip.invalidate(reason: .actionPerformed)
            } label: {
                Label("Favorite", systemImage: "star")
            }

            Text("☆をタップすることでどのようなことができるかをヒントとして提示させることができていますね\n\nTipのバツボタンを押せば閉じることができます")
            Spacer()
        }
        .padding()
        .navigationTitle("TipView")
    }
}

実装コードを実行した時の画面

簡単な実装でTipが表示できることがわかりますね!

ハンドリングできるもの

Tipは単に初回表示させるだけでなく、表示頻度や条件を満たす場合に表示させたりすることが可能です

表示頻度

configureメソッドで指定することができます

Tips.configure(
     [
          // 1日ごとの場合
         .displayFrequency(.daily)
     ]
)

1時間ごと、1日ごとなど表示頻度を調整できます

DisplayFrequency developer.apple.com

Tips.configure()メソッドでは他にもTip周りのデータをどこに保存するかも指定できます(この記事では割愛します)

datastoreLocation(_:) | Apple Developer Documentation

表示ルール

TipにEventを設定して、ログイン済みかどうかや特定の画面を指定回数表示されたことを契機にTipを表示させることができます

developer.apple.com

この後の活用検討でコードや動作を紹介していきます

アクション

Tip上のリンクからアクションとして画面に遷移させたりできます

developer.apple.com

こちらも、この後の活用検討でコードや動作を紹介していきます

Tipの活用を考える

ようやくになりますが、ここからTipの活用に関して考えていこうと思います

次のようなアプリを想定してみます

  • ポイントが貯められアプリ内のポイントカードで確認できる

  • ポイント利用にはログインが必要となる

そういったアプリでは次のようなケースのユーザーが眠っていそうですね

  • アプリ利用してポイントは溜まっているが、いまいちポイントの使い方がわからない
  • キャンペーンがある時に利用したいがいつ実施されているかわからない

そこでTipで次のような施策はどうでしょうか?

ログイン状態のユーザーにポイントを使ったお得なキャンペーンを活用してもらう

次のような条件でTipを表示させてみるとどうでしょうか?

「アプリがログイン状態」かつ「ポイントカード画面を指定回数表示」

の二つの条件でTipを表示させます

次のような実装になります

/// - Tipの定義

// Tip側でEventとルールを設定する
struct CampaignTip: Tip {

    @Parameter
    static var isLoggedIn: Bool = false

    // 画面表示を扱うイベント
    static let enteredView = Event(id: "CampaignEnteredView")

    ・・・

    var rules: [Rule] {
        [
            // ログイン状態かどうかを判定するルール
            #Rule(Self.$isLoggedIn) {
                $0 == true
            },
            // 画面表示回数が指定回数以上か判定するルール
            #Rule(Self.enteredView) {
                $0.donations.count >= 3
            }
        ]
    }
}

・・・
/// 画面表示

// 画面表示のイベントを発火させる
Task { await CampaignTip.enteredView.donate() } // SwiftUIならonAppear, UIKitならviewDidAppearなど

・・・
/// ログイン処理またはログイン状態を取得できる場所

// ログイン状態をTipに伝える
CampaignTip.isLoggedIn = true // static定義してあるためTipインスタンスを画面単位で管理したりは不要

動作は次のようになります(長いのでYouTubeリンクで🙏)

動画で見る通り指定回数の表示でTipが表示され、一度閉じると表示されないことがわかりますね (下の画面表示回数はCampaignTip.enteredView.donations.countを用いて回数を表示させています)

アクションを定義することで画面を表示させることもできますね!

/// - Tipの定義
struct ActionTip: Tip {
    ・・・
    // アクションの定義
    var actions: [Tips.Action] {
        Tips.Action(id: "campaign", title: "キャンペーンページへ")
    }
}

・・・
/// - どこかのTipを表示したいView
・・・
var body: some View {
・・・
    TipView(campaignTip, arrowEdge: .top){ action in
        if action.id == "campaign" {
            needsCampaign = true
        }
    }
     .sheet(isPresented: $needsCampaign) {
         // Tipの"campaign"に一致する場合キャンペーン画面を表示     
         CampaignSheetView()
      }

Tipのアクションからキャンペーン画面を表示させています

ポイント利用できるキャンペーン画面に遷移させてあげたりなどできそうですね!

まとめと応用例

TipKitアプリの新機能を紹介したり、ユーザーが知らないアプリの有用な機能を把握してもらうきっかけにすることができます

シングルページのシンプルなアプリでなければ、"もっとユーザーに知ってもらいたい"という機能であったり、"こういった利用をするとさらにアプリで便利になれる"といったことを伝えたい需要は尽きないのではないのでしょうか?

TipKitではユーザーの行動に従った表示のカスタマイズも可能なため、より訴求力のあるものとして期待が高まります

最後に

ヤプリでは日常のプロジェクト業務だけでなく、こういった新しいフレームワークを試して今後のプロダクト進化の種を探していくことも進めています

ご興味を持たれた方はぜひカジュアル面談にお越しください🙌

open.talentio.com

参考