はじめに
LiDARセンサー付きの iPhone がどうしても欲しくて、最近自身のスマホを iPhone 12 Pro に機種変更しました。
早速、LiDARセンサーの性能を試すべく、Multipeer Conectivity で連携できる自作のARアプリをiPhone 12 ProにXcodeでビルドし、あらかじめ用意してあったもう一台のiPhoneとともにアプリを立ち上げたのですが、
あれ?デバイス同士の連携ができない......?
と異変に気づき、Xcode でコンソールを確認してみると、
2020-12-01 00:34:28.593776+0900 MCSample[28078:11026553] [MCNearbyServiceBrowser] NSNetServiceBrowser did not search with error dict [{
NSNetServicesErrorCode = "-72008";
NSNetServicesErrorDomain = 10;
}].
2020-12-01 00:34:28.593778+0900 MCSample[28078:11026556] [MCNearbyServiceAdvertiser] Server did not publish: errorDict [{
NSNetServicesErrorCode = "-72008";
NSNetServicesErrorDomain = 10;
}].
という今まで見たことのないエラーログが出ているではありませんか...!
「なぁにこれぇ」って武藤遊戯みたいな反応 になったのですが、調べまくってなんとか解決できたので、ここにその方法を残しておこうと思います。
エラーの原因
今回上記のエラーが発生した iPhone 12 Pro は初期搭載OSバージョンが iOS 14.1でした。
手元でさまざまなOSバージョンの端末で試してみたのですが、そもそも上記のエラーは iOS 14から発生していることがわかりました。
そのことから、iOS 14から追加された新機能に絞って調べてみると、WWDC 2020 の Support local network privacy in your app のセッション で、iOS 14からローカルネットワークへの通信にユーザの許可が必要になったことがわかり、そのための追加実装が抜けていたことが今回のエラーの原因だったとわかりました。
解決する方法
このエラーを解決する方法はApple公式ドキュメントである Discovering Peers with MultipeerConnectivity | Apple Developer Documentation の「Add Bonjour Services Plist Keys」の章にちゃんと記載されていました。
が、ドキュメントを読んでいて、解釈が少々わかりづらいポイントがあったので、その点については後述します。
① ローカルネットワークの利用許可ダイアログの説明文を追加する
まず、今回の対応を行うことで表示されるようになる以下のダイアログの説明文をInfo.plist
に追加します。
Property Listから追加する場合は、Privacy - Local Network Usage Description
の値に 利用許可を求める説明文 を追加しましょう。
Source Codeから追加する場合は、以下のように追記しましょう。
<key>NSLocalNetworkUsageDescription</key>
<string>利用許可を求める説明文</string>
② Bonjour サービスで検索するサービス名の追加
Bonjour(ボンジュール)って急にフランス語が出てきて草生えたのですが、
Bonjour とは、Apple社が開発・提供し、Mac/iPhoneに標準装備されているネットワーク機器を何の設定も行わず簡単に接続するための技術 の名称でした。
https://developer.apple.com/bonjour/
iOS 14以降の Multipeer Connectivity では、Bonjour サービスで検索するために、Info.plist
に検出してもらうサービス名を追加する必要があります。
ここで、公式ドキュメントである Discovering Peers with MultipeerConnectivity | Apple Developer Documentation の「Add Bonjour Services Plist Keys」の章を見直してみると、NSBonjourServices
に追加する._tcp
と._udp
のプレフィックスはそれぞれ_myAppName
と記載されています。ここが大きなハマりポイントでした。
最初ドキュメントを見たときに、_myAppName
って Product Name もしくは Display Name のことかな? と思って試してみたのですが、全然違いました 😇
困り果ててググってみると、 Apple Developer Forums で同じ問題に対するQ&Aの回答 を発見し、完全に理解しました。
_myAppName
とは、MCNearbyServiceAdvertiser と MCNearbyServiceBrowser の生成時に共通で使用する serviceType: String の先頭に_
を加えた文字列のことだったのです。
なので、Info.plist
には、
Property Listから追加する場合は、以下のように Bonjour services
の Array に
_serviceType._tcp
と _serviceType._udp
の Item をそれぞれ追加しましょう。
Source Codeから追加する場合は、以下のように追記しましょう。
<key>NSBonjourServices</key>
<array>
<string>_serviceType._tcp</string>
<string>_serviceType._udp</string>
</array>
以上の①、②の対応を行い、再度ビルドすることで無事にエラーが出なくなり、連携できるようになりました。
まとめ
- iOS 14以降で Multipeer Conectivity を利用するには、ローカルネットワークの利用許可ダイアログの説明文とBonjour サービスで検索するサービス名の
Info.plist
への追加が必要になった - 対応方法が記載されている Discovering Peers with MultipeerConnectivity | Apple Developer Documentation の「Add Bonjour Services Plist Keys」の章の
_myAppName
には MCNearbyServiceAdvertiser と MCNearbyServiceBrowser の生成時に共通で使用する serviceType: String の先頭に_
を加えた文字列を使うことが正解