UnityのiOSビルドしたアプリケーションでのディープリンクパラメータの取得と表示

# 1. はじめに
ディープリンクを活用することで、アプリを特定の状態で起動することができます。
この記事では、UnityでディープリンクのURLからパラメータを取得し、それを画面上に表示する方法を学習のアウトプットのために書いていきます。

自分はUnityもC#も初心者なので、間違っている点や改善点などあればご教示いただけますと幸いです。

### ディープリンクとは？
特定のURLをクリックすると、そのURLに関連付けられたアプリが直接特定の画面や状態で開始される機能を指します。
例えば、メールアプリからのリンクをクリックすると、そのリンクに関連付けられたアプリの特定のページが直接開く、といったものです。


# 2. 前提条件
**環境**
Unityバージョン 2022.3.2f1
MacOS Ventura
M1チップ

事前にXCodeのインストールとiOSをビルドできるUnityEditorを準備してください。



# 3. 実装手順
ディープリンクパラメータの取得と表示をするUnityアプリケーションを作成し、XCode側でCustom URL Schemeの設定をします。


## 3.1 コーディング
新規プロジェクトを立ち上げ、Hierarchyタブにて`Create Empty`でGameObjectを、`UI > Legacy > Text`でTextオブジェクトを作成します。
![スクリーンショット 2023-08-23 11.58.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/bbf07a3a-1c4d-70a4-9531-976da2038cf4.png)

Projectタブにて、Assets配下に`Create > C# Script`でC# Scriptを作成します。
![スクリーンショット 2023-08-23 12.01.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/ce6d71f8-0d24-10f1-11e7-859ea49d4324.png)

新規作成したC# ScriptをGameObjectにドラッグ&ドロップします。
![タイトルなし.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/ded19c43-4b5b-4e80-845c-2f482941cf1c.gif)

作成したC# Scirptを開きコーディングしていきます。

UnityEditor上でディープリンクの動作テストをするために、`ContextMenu`を使っていきます。

https://docs.unity3d.com/ja/current/ScriptReference/ContextMenu.html

以下は、ディープリンクが呼ばれた時の処理である`onDeepLinkActivated`関数を擬似的に呼び出すコードです。

```C#
private void onDeepLinkActivated(string url)
{
    Debug.Log(url);
}

private void Awake()
{
    Application.deepLinkActivated += onDeepLinkActivated;
}

[ContextMenu("DeepLinkTest")]
public void DeepLinkTest()
{
    onDeepLinkActivated("myapp://test?param1=hello");
}
```
### ちょっと解説
Application.deepLinkActivatedはディープリンクによってアプリが起動した時に発火するイベントのことです。

https://docs.unity3d.com/ja/2021.1/ScriptReference/Application-deepLinkActivated.html

Awake内の `+=` 演算子は、C#においてイベントハンドラを追加するためのもの。
これにより、`Application.deepLinkActivated` イベントが発生するたびに、`onDeepLinkActivated` 関数が自動的に呼び出されるようになります。

これでUnityEditor上から`DeepLinkTest()`を呼び出せるようになりました。
スクリプトをアタッチしたオブジェクトのInspectorにてスクリプトのコンポーネントの縦3点リーダーを右クリックすると、
画像のように作成した関数が表示されているはずです。
![スクリーンショット 2023-09-13 2.11.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/1d983724-fe67-e9f4-e6c5-045f698cb9be.png)

表示されている関数を押下することでその関数の処理を実行することができます。
これで、`myapp://test?param1=hello`がConsoleに表示されたらOKです。


次にディープリンクでアプリが起動した時にディープリンクのURLからパラメータを取得できるようにします。
linqを使うため、スクリプト上部にて`using System.Linq;`を宣言します。

```C#
private string displayText = "";

private void GetParams(string url)
{
    var uri = new Uri(url);

    var queryStr = uri.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);

    var queries = queryStr
        .Split('&')
        .Select(x => x.Split('='))
        .Where(x => x.Length == 2)
        .ToDictionary(x => x[0], x => x[1]);

    string tmpDisplayText = "";
    foreach (KeyValuePair<string, string> query in queries)
    {
        tmpDisplayText += query.Key + ": " + query.Value + "\n";
    }
    displayText = tmpDisplayText;
}
```
### ちょっと解説

Uriクラスを使ってURLのパラメータ情報を取得します。
```C#
var uri = new Uri(url);
```

URIからパラメータを取得する処理について、
以下のサイト様を参考にクエリをDictionary型で`queries`変数に格納しています。

https://nekojara.city/unity-webgl-current-url#%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%97%E3%81%A6Dictionary%E5%BD%A2%E5%BC%8F%E3%81%A7%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B

`Key: Value`の形で改行して表示するためにDictionary型で格納したqueriesをforeachで回し、
`Key: Value`と改行を`tmpDisplayText`に追加します。


次に、画面上に表示させる処理部分です。
UIのTextオブジェクトに情報を反映させるために、スクリプト上部にて`using UnityEngine.UI;`を宣言します。
そしてTextオブジェクトに反映させるためのスクリプトを書きます。
```C#
public Text textComponent;

private void ApplyTextChange()
{
  if (textComponent != null)
  {
    textComponent.text = displayText;
  }
}
```
上記を書いたらUnityEditorに戻って、`GameObject`のスクリプトコンポーネントに`TextComponent`が追加されているのを確認し、
Textオブジェクトを以下GIFのようにドラッグ＆ドロップします。
![textComponent.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/17b57231-2bf3-23a4-e514-069c7298e8d2.gif)

最後に`onDeepLinkActivated()`にて、Debug.Logを削除し、上記２つの処理を呼び出します。
```C#
private void onDeepLinkActivated(string url)
{
  GetParams(url);
  ApplyTextChange();
}
```

完成したスクリプトはこちら。

```C#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
using System.Linq;

public class DeepLinkScript : MonoBehaviour
{
    public Text textComponent;
    private string displayText = "";

    private void GetParams(string url)
    {
        var uri = new Uri(url);

        var queryStr = uri.GetComponents(UriComponents.Query, UriFormat.SafeUnescaped);

        var queries = queryStr
            .Split('&')
            .Select(x => x.Split('='))
            .Where(x => x.Length == 2)
            .ToDictionary(x => x[0], x => x[1]);

        string tmpDisplayText = "";
        foreach (KeyValuePair<string, string> query in queries)
        {
            tmpDisplayText += query.Key + ": " + query.Value + "\n";
        }
        displayText = tmpDisplayText;
    }
    private void ApplyTextChange()
    {
        if (textComponent != null)
        {
            textComponent.text = displayText;
        }
    }

    private void onDeepLinkActivated(string url)
    {
        GetParams(url);
        ApplyTextChange();
    }

    private void Awake()
    {
        Application.deepLinkActivated += onDeepLinkActivated;
    }

    [ContextMenu("DeepLinkTest")]
    public void DeepLinkTest()
    {
        onDeepLinkActivated("https://www.google.com/test?param1=hello");
    }
}

```
コーディングが完了したら、UnitiyEditor上から`DeepLinkTest`を呼び出してテストしてみましょう。
上記コードの場合、Gameビューにて`param1: hello`と表示されたら成功です。

コーディングが完了したのでビルドしていきます。
`File > Build Settings...`でビルドの設定画面を開き、現在選択しているシーンを追加します。
`SwitchPlatform`でPlatformをiOSへ変更します。
![スクリーンショット 2023-09-13 15.32.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/8823eaaf-dd99-64fa-7e7e-1935104eeb6d.png)

そして`Build and Run`をすると保存先フィルダーを選択後ビルドが走り、XCodeが立ち上がるはずです。

## 3.2 XCode側の設定
XCodeでCustom URL Schemeを設定して、ディープリンクを設定します。
`Unity-iPhone > info.plistファイル`を開き、`URL types > Items 0 () > URL Schemes > Item 0`にスキームを設定します。
自分の場合、`myapp`としました。
![スクリーンショット 2023-09-13 16.55.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/bc506f90-1b90-18bf-3931-6b296fdf2149.png)

シミュレータを起動してSafariを開き、試しに`myapp://test?params=hello&params2=wow`を開いてみます。
するとディープリンクでアプリが起動し、画面にパラメータが表示されます。
![simulator.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3516561/729448bc-898b-ebc3-5a9e-05866b148caf.gif)

これにてディープリンクからパラメータを取得して表示させる実装は完了です。

# 4. まとめ
ディープリンクを活用することで、アプリの特定の部分や機能に直接アクセスさせることが可能となり、ユーザビリティの向上が期待できます。
今回の記事を通して、自身が学んだディープリンクからのパラメータの取得方法や、それをUI上で表示する手法を共有しました。
少しでも誰かの手助けになれば幸いです。


## 参考リンク
https://nekojara.city/unity-webgl-current-url#%E3%82%AF%E3%82%A8%E3%83%AA%E3%83%91%E3%83%A9%E3%83%A1%E3%83%BC%E3%82%BF%E3%81%AE%E5%86%85%E5%AE%B9%E3%82%92%E8%A7%A3%E6%9E%90%E3%81%99%E3%82%8B

https://zenn.dev/tkada/articles/cb8e3c54f647c2

https://dev.classmethod.jp/articles/ios-custom-url-scheme/