iOS, iPadOSからphonelink(tel:...)を開く仕様差分に苦労した話

## まえがき

アプリ内からdeeplinkで電話アプリを起動する実装で、基本設計時に見落としていたハマりポイントがあったので共有。
今回のGOALは、[PhoneLink](https://www.notion.so/lancers-group/%22%3Chttps://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/PhoneLinks/PhoneLinks.html%3E%22)を処理できる端末を使用しているユーザーにのみ、Phone Linkのdeeplink関連の機能を提供すること。そのために、**デバイスがPhoneLinkを使用できるか判断できるようにする**。

## FaceTimeとPhoneアプリの仕様差分について

読み進めていく前に理解しておきたい機能群を抜粋.

### FaceTime

- Wi-Fi経由でAppleユーザーの端末(iOS, iPadOS)への通話、デバイスのセルラー経由での通話ができる

> WiFi経由で、またはサポートされている iOS または iPadOS デバイスのセルラー経由で FaceTime を使用できます。

- 設定 > FaceTime > FaceTimeのノブを`ON`にしないと受信などが使えない (方法は以下)

> 1.「設定」を開きます。
> 2. 「FaceTime」をタップし、「FaceTime に Apple ID を使用する」をタップします。
> 3. Apple ID でサインインします。
> 

https://support.apple.com/en-us/HT204380

### Phone

- デバイスのセルラー経由で電話するアプリ
- 固定電話、国際電話も考慮されて設計されている
- (個人的なメモ)+ボタンは、+が表示されるまで`0`を押すと入力することができる

> 国際電話で「+」を入力する: 「+」が表示されるまで「0」キーをタッチしたままにします。
> 

https://support.apple.com/ja-jp/guide/iphone/iph3c993cbc/ios

## PhoneLinkを開いた時のiOSとiPadOSの仕様差分

### iPadOS:

- 電話に使用するアプリは**Facetime**
- 近くに同じAppleIDにサインインされている＆適切なSIMが挿入されているiPhone or iPadがあれば、そちらの端末のFaceTimeからセルラー経由で発信
- iPad側で設定 > FaceTimeをONにしていないと、通話モーダルが表示されず**何も起きない**

### iOS📱

- 電話に使用するアプリは**Phone**
- 通常の電話アプリなので、固定電話への電話も想定されている

## 困ったこと発生

※2023/11/21現在
iPadでデフォルトで立ち上がるFaceTimeでは、冒頭が2桁の電話番号の冒頭に国別番号を追加して次の`0`が省略されず発信されることが判明。Appleのサポートに問い合わせてみたところ、明確な返答が得られなかったため、共有。

1. `05-1111-2222`の冒頭に、+81の国別コードを付与して、`+8105-1111-2222`に電話
2. FaceTimeに表記上は、`+81(0)5-1111-2222`に電話をかけられているものの、期待値`+815-1111-2222`ではない電話番号に通話されている

## 今回使用するAPIについて

### UIApplication - canOpenURL

```
func canOpenURL(_ url: URL) -> Bool
```

- 戻り値について

> アプリがURLスキームを処理できるかどうかを示すブール値を返します。
> 

ここで言うアプリはOSのこと？インストールされているアプリのこと？


- 引数について...(一部抜粋)

> 実行時に、システムは、デバイスにURLのスキームを処理するために登録されたアプリがインストールされているかどうかを判断します。デバイスには、1つのスキームを処理するために複数のアプリが登録されている可能性があります。
> 

つまり、メソッドの説明の「アプリ」と言うのはインストールされているアプリのことだったんだ！

### 仮説を立てる

=> ここまでの見解が正であれば、

telスキーマのPhoneLinkを直接処理できるアプリ(Phone, FaceTime)を全て削除すれば、

```
UIApplication.shared.canOpenURL(URL(string: "tel:080000"))

```

**上記の構文で`false`が返ってくるはず**

## 試したこと1

### Phone, FaceTimeアプリを削除する

1. iPadでFaceTimeを削除(Setting > Storage > FaceTime > delete)
2. 設定 > FaceTime > Call from iPhoneをオフ(近くのiPhoneを検出して電話しないようにする)

=> 変わらずtrueがまだ返ってくる...

## 試したこと2

### info.plistのLSApplicationQueriesSchemesにtelを追加する

```
<key>LSApplicationQueriesSchemes</key>
<array>
    <string>tel</string>
</array>

```

https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html

=> 変わらずtrueがまだ返ってくる...

## 結果(考察)

- Appleのドキュメンテーションに記載の以下の「アプリ」は「OS」を示している可能性が高い

> アプリがURLスキームを処理できるかどうかを示すブール値を返します。
> 

## 参考文献

※1 [国立国会図書館サーチ - 国別コード一覧](https://www.notion.so/lancers-group/%22%3Chttps://iss.ndl.go.jp/help/help_ja/help_country_codes.html%3E%22)

[PhoneLink](https://www.notion.so/lancers-group/%22%3Chttps://developer.apple.com/library/archive/featuredarticles/iPhoneURLScheme_Reference/PhoneLinks/PhoneLinks.html%3E%22)

[UIApplication](https://www.notion.so/lancers-group/%22%3Chttps://developer.apple.com/documentation/uikit/uiapplication%3E%22)

[canOpenURL](https://www.notion.so/lancers-group/%22%3Chttps://developer.apple.com/documentation/uikit/uiapplication/1622952-canopenurl/%3E%22)