iOS
iOS2Day 24

ディープリンク技術についてまとめてみた

概要

ディープリンクとは、スマホアプリの特定のコンテンツヘ、直接遷移するリンクのことを指します。
「○○アプリを起動する」というようなボタンやリンクを押すと、その対象のアプリが起動する、
といったものを実現させたい時に、この技術を使います。

iOSにてディープリンクを実現するための技術として、
「Custom URL Scheme」や「Universal Links」というものがあります。
今日は、それらがどういうもので、どこが違うのかという点や、それぞれの実装方法をまとめてみました。

Custom URL Scheme

概要

  • ディープリンク技術の1つ
  • cm-app:// のような任意のURL Schemeを決める
  • そのURLが開かれた時に、アプリが起動するように実装する
  • iOS6.0~対応

どういうユーザー体験になるか

cm-app://hogehoge というリンクを踏むと・・・

アプリがインストールされている場合

  • アプリ起動に関するダイアログが表示される
  • 「Open」等を選択するとアプリが起動する

未インストールの場合

  • エラーになり、アプリは起動しない
  • ストアに飛ばしたり等したい場合は、Webサイトorアプリで、別途実装が必要

実装方法

Info.plistにURL Schemeを定義するだけ

スクリーンショット 2017-10-17 22.48.33.png (269.7 kB)

そうすると、こんな感じで起動することができる

スクリーンショット 2017-10-17 22.51.43.png (257.6 kB)

起動後の処理を出し分けることも出来る

どのようなURLから起動されたかを取得することが出来るので、
それによって処理を出し分けることが出来る。
(例)
cm-app://setting → 設定画面を開く
cm-app://profile → プロフィール画面を開く

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    print("url : \(url.absoluteString)")
    print("scheme : \(url.scheme!)")
    print("host : \(url.host!)")
    print("port : \(url.port!)")
    print("query : \(url.query!)")
    return true
}
url : cm-app://hostname:8080/test?name=taro
scheme : cm-app
host : hostname
port : 8080
query : name=taro

Universal Links

概要

  • Custom URL Schemeの上位互換(だと私は思っている)
  • 特定のHTTP or HTTPS のURLをアプリと紐付ける
    • クライアントに、紐付けたいURLを設定する
    • サーバー上に、クライアントの情報を記載した設定ファイルを設定する
  • iOS9.0~対応

どういうユーザー体験になるか

https://sample.jp/news/index.html というリンクを踏むと・・・

アプリがインストールされている場合

  • アプリが起動する
  • ダイアログは表示されず、シームレスにアプリ起動

未インストールの場合

  • そのURLが指定するコンテンツが開かれる
  • 未インストールの場合向けの実装はいらない

実装方法

クライアント

1. Associated Domains を追加して、

  • Domains:applinks:hostname(例 : applinks:sample.jp
  • ここを設定すると、自動的にhoge.entitlementsが編集される

スクリーンショット 2017-10-17 23.56.04.png (165.8 kB)

2. Provisioning Profileを更新するだけ

スクリーンショット 2017-10-17 23.56.14.png (213.1 kB)

3. 起動後の処理を出し分けることも出来る

こちらでも、どのようなURLから起動されたかを取得することが出来るので、
それによって処理を出し分けることが出来る。

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
    if userActivity.activityType == NSUserActivityTypeBrowsingWeb {
        print(userActivity.webpageURL!)
    }
    return true
}

サーバー

設定ファイルを置くだけ

  • https://hostname/apple-app-site-association or https://hostname/.well-known/apple-app-site-associationファイル名に .json はつけない
  • アプリの情報としては、appID(TeamID + Bundle Identifier)が必要
  • pathのフィルタリングが出来る
{
    "applinks": {
        "App": [],
        "details": [
            {
                "appID": "9JA89QQLNQ.com.apple.wwdc",
                "paths": [ "/wwdc/news/", "NOT /videos/wwdc/2015/*"]
            },
            {
                "appID": "TeamID.bundleIdentifier",
                "paths": [ "*" ]
            }
        ]
    }
}

セキュリティ面でも優れている

  • Custom URL Schemeでは、対象のディープリンクを、他のアプリが捕捉することが可能だった
  • Universal Linksでは、以下の3点により、その点が解決されている

固有性

  • 標準的なHTTPやHTTPSのウェブサイトへのリンクを使う
  • 他アプリから同一のものを指定することはできない

安全性

  • サーバ上の設定ファイルによって、このアプリが当該URLを開いても問題ないことを確認する
  • 対象サーバに設定ファイルをアップロードできるのは、対象の開発者だけなので、 ウェブサイトとアプリケーションとの関連づけは安全なものになる

非公開性

  • 他のアプリケーションがインストール済みか否か確認せずに、特定のアプリケーションに対して通信できる

トラブルシューティング

アプリが起動しない

  • サーバー側の設定ファイルのアプリ情報の間違いを疑おう!
  • アプリインストール時に、紐付けが行われる
  • インストール時のログを見よう
  • どういうアプリ情報で、サーバーへ確認しに行ってるかが分かる

ログを見る方法

  • Xcode > Window > Device and Simulators
  • キーワード:swcd

Xcode6DeviceConsole.png (302.8 kB)

iOS9.1だけアプリ起動しない

  • https://hostname/apple-app-site-associationhttps://hostname/.well-known/apple-app-site-associationの両方に設定ファイルを置こう
  • 基本はどちらかでいいが、iOS9.1はルート直下しか見てくれないらしい

まとめ

Universal Linksの方が、ちょっとだけ実装が面倒な感じがしますが、
そのコスト以上の恩恵がたくさん受けられます。
食べログだったり、クックパッドだったり、Web上のコンテンツとアプリを
密接につなげたい場面で、特に活用されているようです。

Androidでも似たような技術で、Digital Asset Linksというものがあったりします。
ディープリンク技術を上手く活用して、更なるUXの高みを目指していきましょう!

アドベントカレンダーも明日で最後ですね!トリの方、よろしくお願いします!!