【iOS】ユニバーサルリンクでアプリを開けるようにする

【iOS】ユニバーサルリンクでアプリを開けるようにする

目次

この記事の存在意味

  • 実際にハンズオン形式で解説している記事がなかったため環境や構成からシンプルで動作を確認できるものを紹介する
  • 自分がはまった部分の解決法をとりあえず解説(2つのドメインが必要なのをCloudFlarePagesで2つページを作って解決した)

前提知識

Webサイト側で用意するもの

  • AASA(Apple App Site Association) : このサーバーが指定したアプリにユニバーサルリンクを使いたいことを明示する
  • ドメイン2つ : 1つのメインドメインと1つのサブドメインでもいい
    • 1つのドメイン内でパスを切り替えることでアプリを開くようにする場合は、「自動でアプリを起動」できないことに注意が必要

iOSアプリ側で用意するもの

  • Associated Domainsの設定 : XCodeで設定が必要です
  • アプリストアへのアプリのArchive : Xcodeでアプリを公開する必要がります。

今回作成する構成の全体像の説明

今回実装する構成

  • Web側
    • CloudFlarePages : 2つのページを作ってユニバーサルリンクをユーザーが踏んだら自動でアプリを起動するようにします
      • メインページ : ユーザーがユニバーサルリンクを踏む
      • サブページ : ユニバーサルリンク先
    • htmlのみのシンプルなページ
    • 2ページ目には「AASA」を持たせる
  • iPhone側
    • ユニバーサルリンクで開かれるだけのシンプルなアプリ
    • ユニバーサルリンク用の設定以外は特に特殊なことはしない

以下の図のようなイメージとして持っていただければいいかと思います。

今回作成したアプリは以下のリンクにあります。

Webサイトの作成

まずはWeb側の実装を行います。

1. GitHubでリポジトリを作成してフォルダ構造を作る

今回は、2つのドメイン(ページ)を使用します。

今回使うCloudFlarePagesにはGithubなどにあるリポジトリから直接デプロイする機能があり、今回はその機能を使いたいので「ブランチを分けてそれぞれのページを分割」しようと思います。

  • メインページ(1ページ目) : main ブランチ

    • フォルダ構造

      1
      2
      root/
      └ index.html
  • サブページ(2ページ目) : sub ブランチ

    • フォルダ構造

      1
      2
      3
      4
      root/
      ├ .well-known/
      │ └ apple-app-site-association
      └ index.html

2. main ブランチのルート直下に置くindex.htmlを作成

サブページへのリンクを張るlocation.hrefのurlは一度CloudFlareにデプロイしないとurlがわからないのでとりあえずは適当な文字列で大丈夫です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ユニバーサルリンク起動テスト</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: sans-serif;
background-color: #f5f5f5;
padding: 2em;
text-align: center;
}

h1 {
margin-bottom: 1.5em;
}

button {
padding: 1em 2em;
font-size: 1.1em;
background-color: #007aff;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
min-width: 300px;
}

button:hover {
background-color: #005ecb;
}
</style>
</head>

<body>
<h1>ユニバーサルリンク起動テスト</h1>
<div>
<button onclick="location.href='https://test.example'">アプリを開く<br><small>(別ドメイン)</small></button>
</div>
</body>
</html>

3. sub ブランチのルート直下に置くindex.htmlを作成

こちらはデザインも適当で大丈夫です。
存在していることが大切なページになります。

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>アプリにリダイレクト中...</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<p>アプリを開いています...</p>
</body>
</html>

4. sub ブランチに配置するユニバーサルリンク用の設定ファイルのapple-app-site-associationを作成

このファイルは形式としてはjsonですが拡張子は「つけない」で保存してください。

appIDの項目は「アプリをAppleのデータベースに登録してから発行される」ので、とりあえずはこのままの記述で大丈夫です。後で変更します。

1
2
3
4
5
6
7
8
9
10
11
{
"applinks": {
"apps": [],
"details": [
{
"appID": "App ID Prefix.BundleID",
"paths": [ "/*" ]
}
]
}
}
  • appID : アプリの識別子
    • BundleID : ユーザーが自分でつけるアプリのID
    • App ID Prefix : Appleが自動で指定するID
  • paths": [ "/*" ] : どのページにユーザーが飛んできたときにユニバーサルリンクとして発火するか

CloudFlarePagesの設定

まずは、以下の作業を自分で終了させてください。

  • CloudFlareのアカウント作成
  • GitHubの連携
  • Pageを作成する画面を開く

バージョンの変化によってすぐにレイアウトが変わるのでイメージ程度に読み進めてください。
レイアウトが変わってもざっくりと同じ道筋になるかと思います。

1. Pageの作成

以下のような画面を開いて、「既存のGitリポジトリをインポートする」を選択してください
この時に「Workers」と「Pages」という2つのタブが出てきますが、必ず「Pages」を選択してください。

CloudFlareはWorkersという機能でPagesの機能も踏襲しているからWorkersを使うことを推奨してきますが、今回のようなシンプルな構成では設定がPagesに比べてめちゃくちゃ面倒くさくなるので今回はPagesで行います。

2. 使用するリポジトリの選択

画像のように前のステップで作成したWebサイトが入っているリポジトリを持っているアカウントとリポジトリを選択してください。

選択後、「右下のセットアップの開始ボタン」を押します。

3. ビルドとデプロイのセットアップ

サブページも作るので、1,2の手順を2回繰り返して、以下の画像のように2通りのページを作成する必要があります。
設定する箇所はシンプルでプロジェクト名(これがurlに入ります)、プロダクションブランチになります。

それぞれ画像を参考に設定してみてください。
右下の「保存してデプロイする」を押してデプロイまで行ってください

  • メインページ

    • プロジェクト名 : universal-link-test-main
    • ブランチ名 : main
  • サブページ

    • プロジェクト名 : universal-link-test-sub
    • ブランチ名 : sub

2つのページの作成が完了後、「アカウントホーム」を確認して想定通りのページが作成できているか確認してください。

確認ができたらひとまずWeb側の設定とデプロイは終了です。

iOSアプリの作成

次にアプリの作成を行っていきます。
「universal link」を行うためにはAppleのサーバーにアプリを登録する必要があります。

登録のためには開発者アカウントを作って有料登録をする必要があることに注意してください。

1. プロジェクトの作成

私は以下のような設定で作成しました。
現在の最小構成のプロジェクトの生成設定です。

2. 画面に表示されるテキストを調整

プロジェクトを生成すると自動で生成されるContentView.swiftファイルを以下のように若干変更しました。(任意です)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import SwiftUI

struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "link")
.imageScale(.large)
.foregroundStyle(.tint)
Text(
"ユニバーサルリンクで起動させるアプリ"
)
}
.padding()
}
}

#Preview {
ContentView()
}

3. Appleのデータベースに作成したアプリを登録する

  • アプリアイコンの設定

    • 1024 × 1024の画像を作成(アプリアイコン用)
    • 作成したアプリアイコンを「Assets -> AppIcon -> Any Appearance」に設定

  • Associated Domains設定

    • プロジェクト名 -> TARGETS(プロジェクト名) -> Signing & Capabilities -> + Capability

    • 出てくるポップアップでAssoぐらいまで入力して検索して出てくる「Associated Domains」を選択

    • 追加された項目に以下の画像のように設定を追加します。

    • +ボタンを押して項目を追加して、aaplinks:ドメイン名を入力してください

4. アプリストアにアーカイブ

  • 以下の画像のように「画面上部 Product -> Archive」の順でアーカイブを開始します。
  • ボタンを押すとビルドが走ってアーカイブが開始されます。

  • ビルド後、以下のようなポップアップが出てくるので、今回はストアに掲載したいわけではないので、「TestFlight Internal Only」を選択します。

  • その後に出てくるポップアップは「Next」を選択していれば大丈夫です。なにかエラーが出た場合は解決しないとアップロードできません。

  • TestFlightで自分の端末でダウンロードできるようになるまでの設定の解説はしないのでわからない方は調べてみてください。

Web側の設定の書き換え

各リンクの設定やアプリの情報を設定していきます。

main ブランチのindex.htmlのボタンを押した先のリンクをsubブランチのページに設定

今回私が設定したsubページのurlは以下のurlになっていたのでそれをlocation.href=の対象に設定します。

ページのurlは、赤枠のドメイン部分の前にhttps://を追記した形で大丈夫だと思います

1
2
3
4
5
6
7
8
....
<body>
<h1>ユニバーサルリンク起動テスト</h1>
<div>
<button onclick="location.href='https://universal-link-test-sub.pages.dev'">アプリを開く<br><small>(別ドメイン)</small></button>
</div>
</body>
....

設定を変更後、Commit&Pushすれば自動でPages側で変更を認識して情報を更新してくれます。

sub ブランチの「apple-app-site-association」にアプリのIDを設定する

まずは、一つ前のステップで作成してアプリストアにTestFlightとして登録したiOSアプリの情報を見に行きます。

AppleのDevelopperページから対象のアプリを開いて以下の画像の赤枠の部分をメモします。

その後、sub ブランチにあるAASAを開いて、以下のように「Apple ID.バンドルID」の順で記述します。「Apple ID」と「バンドルID」の間には.を配置します。

1
2
3
4
5
6
7
8
9
10
11
{
"applinks": {
"apps": [],
"details": [
{
"appID": "49BQT24CU7.com.djima.universal-test",
"paths": [ "/*" ]
}
]
}
}

最終テスト

これですべての設定が終了したので、自分のiOS端末にTestFlightでアプリをインストールして、main ブランチのページをWebブラウザから開きます。

以下のようにWebブラウザでボタンをクリックして、アプリが起動したら成功です。

参考

  • 検証するためのTips
Author

Daiki Iijima

Posted on

2025-09-05

Updated on

2025-09-07

Licensed under