iOSのCore Bluetoothでバックグラウンド同士で通信できるのか

iOS×BLE本を書いた時点での僕の見解は「できない」

これとほぼ同様の見解:

・セントラル側はバックグラウンドでスキャンを行うにはService UUIDを明示する必要がある
・ペリフェラル側ではバックグラウンドでアドバタイズを行う際、Service UUIDは"overflow area"に格納される(アドバタイズメントパケットには入っていない)

「でもあのアプリでは通信できますよ?」みたいなことを言われたりもする。このへんはブランクも長いのでもう一度考え直してみた。

可能性としては以下がある。

1. 実は"overflow area"はセントラル側がバックグラウンド状態にあってもアクセスできる(スキャンで発見できる)
2. その後の機能追加でバックグラウンド同士でP2P通信を行うことが可能になった
3. BLE以外の手法を用いてバックグラウンドでのP2P通信を実現している

以下、ググりつつ雑に調べたメモ。(調査は途中/※マガジンを購読して読める領域にも決定的な結論にはまだ至ってないのでご注意ください。機会があればサンプルつくってちゃんと検証します)

------ 追記ここから ------

この記事を書いたのは2020年3月ですが、2020年12月現在、僕の見解は本記事とちょっと変わっています。今年の情勢も相まってBLEを利用して近接検知をバックグラウンドでやろうというのは全世界の人が検討したようで、以下の記事を筆頭に参考になる記事がいくつか出てきました。

自分でも試す機会があり、今の見解としては「バックグラウンド同士での通信は可能」「ただしスクリーン状態に依存」(アプリがバックかフォアかではなく)というものです。上で「可能性」として挙げた『1. 実は"overflow area"はセントラル側がバックグラウンド状態にあってもアクセスできる(スキャンで発見できる)』が的中した形です。overflow areaについても以下に書いたときよりも詳細がわかりました。また機会があればまとめます。

------ 追記ここまで ------

## "overflow area"とはそもそも何なのか?

Appleの公式ドキュメントで明確に"overflow area"という用語が用いられているのは、

ここと、

Any service UUIDs contained in the value of the CBAdvertisementDataServiceUUIDsKey key that don’t fit in the allotted space go to a special “overflow” area. These services are discoverable only by an iOS device explicitly scanning for them.
While your app is in the background, the local name isn’t advertised and all service UUIDs are in the overflow area.

ここ。

All service UUIDs contained in the value of the CBAdvertisementDataServiceUUIDsKey advertisement key are placed in a special “overflow” area; they can be discovered only by an iOS device that is explicitly scanning for them.

"overflow area"とは?という記述はない。

ではここはスキャン側(セントラル側)がフォアグラウンドにないと見つけられないエリアなのか?実はスキャン時に対象となるService UUIDを指定していればアプリがバックだろうとフォアだろうとその"overflow area"まで見に行ってくれるのではないか?

そう思って公式ドキュメントを探してみたが、とくに明確な記述はなかった。

Your app can scan for Bluetooth devices in the background by specifying the bluetooth-central background mode. To do this, your app must explicitly scan for one or more services by specifying them in the serviceUUIDs parameter. 

「バックグラウンドではService UUIDを指定しないといけない」と言ってはいるが、そのService UUIDがoverflow areaにある場合は見つけられない、と明言されていない

ここから先は

440字
文章やサンプルコードは多少荒削りかもしれませんが、ブログや書籍にはまだ書いていないことを日々大量に載せています。たったの400円で、すぐに購読解除してもその月は過去記事もさかのぼって読めるので、少しでも気になる内容がある方にはオトクかと思います。

技術的なメモやサンプルコード、思いついたアイデア、考えたこと、お金の話等々、頭をよぎった諸々を気軽に垂れ流しています。

最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/