iOS 14でローカルネットワークの利用

# はじめに
iOS14からローカルネットワークへの通信にユーザの許可が必要になりました。
例えば、ローカルネットワークに存在する機器を自動検出するために、ブロードキャストやマルチキャストを利用すると、ユーザに以下のようなアラートダイアログが表示されます。iOS14では、ユーザに許可を求めるようになっただけかと思ったのですが、機能によっては、実装の変更やAppleへの申請が必要です。詳細は、参考文献にあげたURLを参照ください。
<img width="250" alt="LocalNetworkPermission.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/9168bab9-c44a-5e43-64ac-2854be4a770d.png">


# iOS14でローカルネットワーク通信に許可が必要な機能
["Support local network privacy in your app (WWDC2020)"]
(https://developer.apple.com/videos/play/wwdc2020/10110/)において、ローカルネットワークへの通信に関して、ユーザに許可がいる場合は、以下と説明されています。

##### ユーザの許可が必要
- TCP/UDPでローカルネットワークのホストに通信
- Bonjourでの検索と広告
- IPマルチキャスト、ブロードキャスト、ICMPでの通信

<img width="700" alt="NeedLocalNetworkPermission.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/60bbd53a-759c-ede2-65c1-b3fdef940b94.png">

# 開発者が変更する必要があること
ローカルネットワークを利用する場合、開発者として必要なことは以下です。

## 1. ローカルネットワークの許可ダイアログの説明文の追加

アプリでローカルネットワークの許可が必要な時に、以下のダイアログが表示されます。何も設定していないと、`はじめに`のような図の標準的な説明文が表示されます。`Info.plist`に説明文を入れることで、このダイアログに説明文を追加することができます。アプリで必要な理由をユーザに説明することができます。

<img width="250" alt="LocalNetworkPermission説明文.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/38553f48-2333-85a4-ef07-9e8937aa02ac.png">

具体的には、Xcodeで`Info.plist`を編集し、`Privacy - Local Network Usage Description`の値が説明文を追加します。
<img width="700" alt="Info.plist.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/5774e0e0-b282-7099-d9f3-dbc07224331e.png">

`Info.plist`のファイルは、以下のようになります。

``` Info.plist
<key>NSLocalNetworkUsageDescription</key>
 <string>この部分に説明を記載してください。</string>
```

## 2. Bonjourで検索するサービスの追加
Bonjourでサービスを検索する時には、`Info.plist`に検索するサービス名を記載します。ここで、記載したサービスは、Bonjourで検出できるようになります。Xcodeで`Info.plist`を編集し、`Bonjour services`に検索するサービスを追記します。配列になっているので、複数記載することが出来ます。

<img width="700" alt="Bonjour.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/ecefdcdc-8ed3-5b10-d477-e0aa6acebafd.png">


``` Info.plist
<key>NSBonjourServices</key>
<array>
　<string>_ipp._tcp.</string>
　<string>_printer._tcp.</string>
</array>
```

## 3. ブロードキャスト/マルチキャスト通信が必要な場合
### Multicast Networking Entitlement申請
上記以外のブロードキャスト/マルチキャスト通信が必要な場合、AppleにアプリIDごとに申請が必要です。具体的には、[「マルチキャストネットワークエンタイトルメント申請(Multicast Networking Entitlement Request)」]
(https://developer.apple.com/contact/request/networking-multicast)から申請できます。
iOSシミュレータおよびiPadOSシミュレータでは、この許可なしで通信できます。しかし、実機では、この許可がないと通信できません。シュミレータで通信できるが、実機で通信できない場合には、この許可が必要かを確認してみてください。

### Multicast Networking Entitlement取得後の設定方法
Appleから`Multicast Networking Entitlement`を取得した後、いくつか設定が必要です。その設定方法を書いておきます。

#### 対象アプリのCapabilitiesの追加 (Apple Developer)
対象のアプリIDを選びます。具体的には、以下の図のApple Developerの`Certificates, Identifiers & Profiles`の`Identifiers`から対象のアプリを選択します。
現時点のURLは、https://developer.apple.com/account/resources/identifiers/list です。

<img width="700" alt="Identifiers.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/1ac83823-bb47-2501-96eb-7828a1b59077.png">

対象のアプリIDを選択すると`Edit your App ID Configuration`でアプリの設定変更ができます。
`Multicast Networking Entitlement`を取得したアプリは、以下の図のように`Additional Capabilities`が選べるようになるので、`Multicast Networking`を選択します。

<img width="700" alt="Capability.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/d2a8fe44-eafd-3bdf-bcbd-59717d3e8445.png">

#### 対象アプリのCapabilitiesの追加 (Apple Developer)
Xcodeで`アプリ名.entitlements`のファイルを選択します。以下の図のように、`key`に`com.apple.developer.networking.multicast`を、`value`に`1`を入れます。
これでCapabilityの設定は完了です。

<img width="400" alt="entitlements.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404406/c1901cae-5dfb-0b0e-fe46-4208ffe6378f.png">

以下のファイルでの記載方法です。

``` アプリ名.entitlements
<key>com.apple.developer.networking.multicast</key>
<true/>
```


# 参考文献
- [Appでマルチキャストネットワークを使用するには]
(https://developer.apple.com/jp/news/?id=0oi77447)
- [Support local network privacy in your app (WWDC2020)]
(https://developer.apple.com/videos/play/wwdc2020/10110/)
- [ Multicast Networking Entitlement](
https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_networking_multicast)