iBeaconの実装 2021年版(iOS 14, Swift 5)
iBeaconが初登場したのが2013年(iOS 7の頃)。そこから2015年ぐらいまでは仕事で触る機会もあったのだが、ここ5年ぐらいはまるっきり縁がなかった。ObjC時代から始まって、最後に実装したのはSwift 2か3だと思う。
で、ひさびさに仕事で実装したので今後自分でコピペする用にSwift 5の最小実装を残しておきたいのと、iOS 13でAPIに色々と変更があったので、本記事に書いておく。
ビーコン領域監視に必要なパーミッション
iOS 8から位置情報取得のパーミッションが「使用中のみ許可 」(NSLocationWhenInUseUsageDescription)と、「常に許可」(NSLocationAlwaysUsageDescription)に分かれた。
「使用中のみ許可」はユーザーがアプリを立ち上げて使用している状態なので、バックグラウンドで位置情報を取得したい場合はNSLocationAlwaysUsageDescriptionを許可してもらう必要がある。
これがiOS 13から、アプリケーションとしてはNSLocationAlwaysUsageDescriptionをリクエストしていても、ユーザーに表示されるダイアログには最初は「常に許可」という選択肢は提示されず、「使用中のみ許可」「一時的に許可」「許可しない」の選択肢だけが表示され、アプリがさらにしばらく使用された場合にだけもう一度ダイアログが出て「常に許可」が選べるという仕様になった。
で、ビーコンの話に戻ると、iOS 13からWhenInUseでもバックグラウンドでの領域監視を行えるようになった。
WWDC 2019のセッション"What's New in Core Location"で明言されている。
手元でもこれでバックグラウンドでの領域監視が行えることを確認した。これは重要情報でありつつ結構知らない人は多いのでは...
CLBeaconIdentityConstraint
iOS 13で追加された新クラス。ビーコンを特定するためのconstraint(制約)として使用する。要はUUID, Major, Minorをひとまとめに管理して「これ」って言うためのクラス。MajorとMinorは省略できて、その場合はワイルドカードとなり、任意のMajor, Minorと一致する。
init(uuid: UUID)
init(uuid: UUID, major: CLBeaconMajorValue)
init(uuid: UUID, major: CLBeaconMajorValue, minor: CLBeaconMinorValue)
これを使用してCLBeaconRegionを初期化できるようになったほか、
init(beaconIdentityConstraint: CLBeaconIdentityConstraint, identifier: String)
これを使用してレンジング開始/停止も行えるようになった。
func startRangingBeacons(satisfying constraint: CLBeaconIdentityConstraint)
func stopRangingBeacons(satisfying constraint: CLBeaconIdentityConstraint)
iOS 13以前は次のようにCLBeaconRegionを指定してレンジングを開始/停止していた(これらはiOS 13でdeprecaetedに)
func startRangingBeacons(in region: CLBeaconRegion)
func stopRangingBeacons(in region: CLBeaconRegion)
CLBeaconRegionのイニシャライザ
iOS 13までは次のようにCLBeaconRegionのイニシャライザは以下だったが(これらはdeprecated)
init(proximityUUID: UUID, identifier: String)
init(proximityUUID: UUID, major: CLBeaconMajorValue, identifier: String)
init(proximityUUID: UUID, major: CLBeaconMajorValue, minor: CLBeaconMinorValue, identifier: String)
iOS 13から次のようになった。
init(uuid: UUID, identifier: String)
init(uuid: UUID, major: CLBeaconMajorValue, identifier: String)
init(uuid: UUID, major: CLBeaconMajorValue, minor: CLBeaconMinorValue, identifier: String)
つまりもうProximity UUIDとは呼ばないということか。
あと、前述したとおりCLBeaconIdentityConstraintでも初期化できるようになった。
ちなみにどのイニシャライザでもidentifierは指定する必要があるみたいだが、これってなくせないのだろうか...CLBeaconIdentityConstraint(UUID/Major/Minor)が同じでも別のidentifierを割り振りたい、みたいなユースケースがある...?
最小実装(領域監視のみ)
以上を踏まえ、iOS 13以降でビーコン領域監視を行うまでの最小実装。
ここから先は
¥ 650
Amazonギフトカード5,000円分が当たる
最後まで読んでいただきありがとうございます!もし参考になる部分があれば、スキを押していただけると励みになります。 Twitterもフォローしていただけたら嬉しいです。 https://twitter.com/shu223/