🦅

[SwiftUI]Cloudflare PagesでUniversal Linksを実装する

2024/04/16に公開

Universal Linksとは

Universal Linksとは、URLからアプリを開くための技術です。
該当するアプリがインストールされている場合はアプリが開き、
アプリがインストールされていない場合は、Webサイトが開きます。

下記のURLは、私が開発しているFujimiというマップアプリのUniversal Linksです。
https://fujimi.ryodeveloper.com/?ll=35.658558,139.745504&q=%E6%9D%B1%E4%BA%AC%E3%82%BF%E3%83%AF%E3%83%BC
ぜひインストールして動作の確認をしてみてください!

類似する技術でCustom URL Schemeというものもありますが、
アプリがインストールされている場合にしか動作しないことや、セキュリティー上の懸念[1]からUniversal Linksが推奨されています。

While custom URL schemes are an acceptable form of deep linking, universal links are strongly recommended.
Apple Developer

Cloudflare Pagesとは

https://pages.cloudflare.com

Cloudflare Pagesとは、Webサイトを公開するためのホスティングサービスです。
Universal Linksを実装するには、関連付けファイルをWebサイトに配置する必要があるため、
ホスティングサービスなどを使用することになります。

Cloudflare Pagesは無料枠で

  • Static Requests制限なし
  • Bandwidth制限なし
  • GitHub連携が可能
  • 商用利用が可能

のサービスを使用できます。
2024年4月現在、もっとも無料枠が大きいホスティングサービスなのではないでしょうか?

1. apple-app-site-associationの作成

関連付けファイルを作成します。
.well-knownフォルダーを作成して、配下にapple-app-site-associationを追加します。
appIDsには、"チームID.バンドルID"を記載します。
チームIDはApp Developer / メンバーシップの詳細から確認できます。

apple-app-site-association
{
    "applinks": {
        "details": [
            {
                "appIDs": [
                    "BGS5U89ZQT.ryodeveloper.Fujimi",
                    "BGS5U89ZQT.ryodeveloper.Fujimi-Dev"
                ],
                "paths": [
                    "*"
                ]
            }
        ]
    }
}

apple-app-site-associationはWebサイトに配置するファイルです。
そのため、各サービスのapple-app-site-associationを確認することもできます。
通常https://fujimi.ryodeveloper.com/.well-known/apple-app-site-associationのように、
ドメイン + /.well-known/apple-app-site-associationにアクセスすることで確認できます。

2. (オプション)Webサイトの作成

先述したように、Universal Linksでは該当するアプリがインストールされていない場合はWebサイトが開きます。
今回は、Igniteを使用してアプリのインストールを促すWebサイトを作りました。
Igniteを使用する場合は、Assetsフォルダーに1で作成した.well-knownフォルダーを入れてビルドします。

Igniteについては、こちらで紹介しています。
https://zenn.dev/ryodeveloper/articles/kame_ga_14_hiki

3. Cloudflare Pagesの作成

Cloudflareのアカウントでログイン後、
Workers & Pages / Pages / Gitに接続 をクリックします。

GitHubを連携後、
2で作成したリポジトリを選択して、
セットアップを開始 をクリックします。

プロジェクト名を入力して、
ビルド出力ディレクトリを指定します。(写真はIgniteを使用した場合です。)
保存してデプロイする をクリックするとWebサイトが公開されます。

Webサイトが公開されました。
しかし、このままでは該当するアプリをインストールしても、開くボタンが表示されません。

4. Associated Domainsの追加

アプリのプロジェクをを開き、
TARGETS / Signing & Capabilities / + をクリックします。

Associated Domainsを選択します。

Associated Domainsに

applinks:3で公開したWebサイトのドメイン

を追加します。
私は、カスタムドメインを追加したのでapplinks:fujimi.ryodeveloper.comのように書きました。

ビルド後にWebサイトを開くと
開くボタンが表示されました。

4. URLに応じた処理

Universal LinksのURLに応じて処理をしたい場合は
onOpenURLメソッドを使用します。
https://developer.apple.com/documentation/swiftui/view/onopenurl(perform:)
今回は、受け取ったURLを画面に表示させます。

ContentView.swift
struct ContentView: View {
    @State var url = URL(string: "")

    var body: some View {
        VStack {
            Text(url?.absoluteString ?? "")
        }
        .padding()
        .onOpenURL { URL in
            url = URL
        }
    }
}

5. 完成🎉

URLが取得できました。
後は、この値を自由に加工するだけです。

サンプル

https://fujimi.ryodeveloper.com/?ll=35.658558,139.745504&q=%E6%9D%B1%E4%BA%AC%E3%82%BF%E3%83%AF%E3%83%BC
上記のWebサイトのコードをGitHubに公開しました。
Forkしてご自身のアプリ用に使用しても構いません。
https://github.com/RyoDeveloper/FujimiSite

脚注
  1. Custom URL SchemeのURLはユニークである必要がないため、他のアプリと同じURLを指定することで動作を乗っ取ることができます。 ↩︎

Discussion