便利な解錠方法-AppClip解錠

この記事は Akerun Advent Calendar 2021 - Qiita の1日目の記事です。

WebエンジニアのBunです。主にiOSアプリの開発を担当しています。

日々いろんな解錠方法について考えています。特にiOSアプリで使えるいろんな便利な機能を使った解錠方法とその実装手順をまとめます。 今回はApp Clipでの解錠について説明します。

App Clipとは

iOS14から使えるApp Clipはアプリの一部分で、アプリの一部機能やコンテンツを必要な時に簡単に見つけて、すばやくアクセスし、体験することができます。

※弊社のAkerunの本体、あるいは近いところに専用QRコード/NFCタグを配置すれば、事前にAkerunアプリをインストールしなくても、1タッチ/1タップでの解錠が実現可能。

以下の特徴があります。

  • 高速で軽量(10MB以下)のため、すばやく起動可能。わずか数秒でダウンロード->インストール->使用まで可能
  • 通常の完全版アプリと同じ方法で開発可能(一部使用可能なiOS SDK制限あり)
  • 同じアプリに複数のApp Clipを作成可能
  • 完全版アプリのダウンロードを促すことが可能
  • 既に完全版アプリがインストールされている場合、完全版アプリが起動される
  • Apple Pay」、「Appleでサインイン」との相性が良い(ユーザー登録、合鍵発行など、良いUX実現可能)
  • App Clip専用の位置情報確認用APIを使用して、App Clipコード/NFCタグ/QRコードが所定場所で使用されているか確認可能
  • App Clipを見つけて、起動する方法は多数ある
    • Apple製のURL/NFCタグが埋め込まれているApp Clipコードをタップしたり、カメラでスキャンしてApp Clipを起動(以下のNFCタグ、QRコードが合体されている)
    • 通常のNFCタグにiPhoneをかざして起動。ロック画面からでも起動可能
    • QRコードを作成し、カメラでスキャンして起動
    • Safari App Banner(Smart App Banner)を使って、WebページのBannerをタップして起動
    • iMessage、Mailで共有されたLinkをタップして起動
    • マップ上のマーカーをタップして起動
    • 「最近追加した項目」カテゴリに表示されるので、そこから再起動
    • App Clip起動から8時間以内であれば、新しいPush通知から再起動可能

App Clipから解錠

URLが埋め込まれたQRコードをカメラでスキャンすると、下記にようにApp Clipがすぐ起動されます。ボタン(Labelはカスタタイズ可能)をタップすると、指定画面に遷移され、解錠処理が実行されます。

App Clipの実装方法

App Clipの追加

  • 既存アプリにApp ClipのTargetを新規追加

  • 「Next」画面でProject名(例えば、既存アプリ名+AppClip)を入力し、UIKit AppかSwiftUI Appを選択

App Clip起動(XXボタンをタップ)した時の処理

App Clipから起動された場合、NSUserActivityがイベントに渡されるので、NSUserActivityからURLを取得、解析後、指定画面に遷移し、処理時実行します。 ※URL例:https://ドメイン/unlock/door?id=1001

  • UIKit Appの場合(Universal Linksと同じ方法)
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        guard let url = userActivity.webpageURL, let components = URLComponents(url: url, resolvingAgainstBaseURL: true) else { return false }
        // componentsからURLパスを解析、Queryなどを抽出し、関連画面に遷移、処理時実行
    }
}
  • SwiftUI Appの場合、Universal Linksと異なって、onOpenURLではなくonContinueUserActivityが呼ばれるので、表示したい画面でイベントを拾う
struct ContentView: View {
    var body: some View {
        NavigationView {
            ...
        }
        .onContinueUserActivity(NSUserActivityTypeBrowsingWeb, perform: handleUserActivity(_:))
    }
}

extension ContentView {
    func handleUserActivity(_ userActivity: NSUserActivity) {
        guard
            let incomingURL = userActivity.webpageURL,
            let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
            let queryItems = components.queryItems
        else {
            return
        }
        
        if let id = queryItems.first(where: { $0.name == "id" })?.value {
            // idの鍵/ドアの解錠処理を行う
        }
    }
}
  • UIKitのSceneDelegateライフサイクルの場合、Univeral Linksと同じ方法で対応
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
    // Univeral Links / AppClip
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        guard
            let incomingURL = userActivity.webpageURL,
            let components = NSURLComponents(url: incomingURL, resolvingAgainstBaseURL: true),
            let queryItems = components.queryItems
        else {
            return
        }
        
        if let id = queryItems.first(where: { $0.name == "id" })?.value {
            // idの鍵/ドアの解錠処理を行う
        }
    }
}

解錠処理の実装

Akerun公開APIで合鍵発行、解錠が可能です。 具体的な実装は割愛します。弊社のAkerun Developersと下記の関連記事をご参照ください。

developers.akerun.com

akerun.hateblo.jp

akerun.hateblo.jp

アプリ本体の対応

既にアプリ本体がインストールされている場合、App Clipではなくアプリ本体が起動されるので、アプリ本体にもUniveral Linksで同じ対応を入れる必要があります。

ドメインの登録

Universal Linksと同じくサーバーのドメインを登録する必要があります。

  • json形式(.json拡張子不要)のapple-app-site-associationファイルを.well-knownに配置し、直接Getできるようにする(Redirectはダメ)

  • apple-app-site-associationファイルにApp ClipアプリのBundle Identifyを追加

{
    "appclips": {
        "apps": [
            "teamId.appId.Clip",
            "teamId.appId.Stg.Clip" ←Staging/Debug版アプリがあれば
        ]
    },
    "applinks": { ←アプリ本体Universal Links用
        "apps": [],
        "details": [
            {
                "appID": "teamId.appId",
                "paths": [
                    "unlock/*", ←解錠
                    "receive/*" ←合鍵受取
                ]
            },
            {
                "appID": "teamId.appId", ←Staging/Debug版アプリのID
                "paths": [
                    "unlock/*", 
                    "receive/*"
                ]
            }
        ]
    }
}
  • アプリ本体とApp ClipアプリのCapabilitiesにAssociated Domainsを追加し、ドメインを設定(アプリ本体にUniversal Links用のドメインも追加)

AppStoreConnectでの設定

App Clipが起動された時の画面表示を設定する場合、アプリをArchiveし、AppStroeConnectにアップロードしてから設定を行います。

  • 基本設定:背景画像、サブタイトル、アクション(ボタンラベル)を設定

  • NFCタグ、QRコードに埋め込むURLを作成したり、App Clipの詳細設定をおこな場合、「高度な体験を編集」をクリックする

apple-app-site-associationを設定すると、エラーは消える。

App ClipのDebug

指定URLから正常にApp Clipが起動されるか以下の方法でDebug可能です。URLのLinkを直接Tapして起動、あるいはNFCタグ/QRコードからの起動が可能です。

Schemeの設定

App ClipのScheme(Run->Arguments->Environment Variables)にテストURLを設定します。

iPhoneでLocal Experiencesを登録

iPhoneの設定->Developer->Local ExperiencesにURLごとの設定を追加します。複数のURLの登録ができ、以下の項目が設定可能です。

  • URL Prefix:Schemeに設定したURLを設定
  • Bundle ID:App ClipのBundle IDを設定
  • タイトル、サブタイトル:任意の文字列
  • アクション(ボタンラベル):一覧から選択
  • 背景画像:任意のPNG/JPEG画像。1800x1200ピクセルで、できるだけ小さいサイズの画像の方が良い

Debugを実施

以下の手順でDebugを実施します。

  • XcodeからApp Clipを起動
  • 上記のURLをSafariで開く。QRコードNFCタグからも起動可能
    • URLのQRコードを生成し、カメラからスキャン
    • 市販のNFCタグを購入し、URLを書き込む
  • URLのLinkをTap(あるいは、QRコードをスキャン/iPhoneNFCタグをタップ)すると、App Clipが起動される

その他

解錠だけではなく、「Appleでサインイン」を使えば、ユーザー登録、合鍵登録も簡単にできそうです。

  • ユーザー登録、合鍵登録用URLを発行する
  • ユーザーにURLを共有する
    • 直接Linkを共有
    • QRコードを共有、あるいは、印刷して指定場所に配置
    • NFCタグにURLを書き込んで、指定場所に配置
  • ユーザーはLinkをTap/QRコードをスキャン/iPhoneNFCタグをTapすることでApp Clipアプリを素早く起動(事前にアプリのインストールは不要)
  • Appleでサインイン」でサインインし、ユーザーを登録/合鍵を受け取る
    • ユーザー登録する場合、ユーザーのApple IDを使って新規ユーザー登録を行う
      • iPhoneで生体認証(顔認証、指紋認証
      • 登録に必要な情報(メールアドレス、Tokenなど)をサーバーに送信し、ユーザー登録を行う
    • 合鍵受け取る場合、「Appleでサインイン」でサインインし、合鍵を受け取る
      • まだユーザー登録されていない場合、ユーザー登録->合鍵を受け取る
      • 登録済みの場合、Apple IDでサインインし、合鍵を受け取る

まとめ

App Clipはユーザーにとても優れたUXを提供できる機能です。

URLベースになっているので、実装上Universal Linksとはそれほど差異がありません。また、設定もシンプルなので、どんどん活用して行きたいですね。

次回は、Widgetについて書こうと思います。


株式会社フォトシンスでは、一緒にプロダクトを成長させる様々なレイヤのエンジニアを募集しています。 hrmos.co

Akerun Proの購入はこちらから akerun.com