8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

iPhoneにBeacon発信機能を実装してみた

Last updated at Posted at 2020-05-13

はじめに

先日アーキテクチャのデザインのレパートリーを増やしたいこともあり気になっていた「Amazon Web Services クラウドネイティブ・アプリケーション開発技法」という本を買いました。本書はAWSを活用したアプリケーションのサンプルがいくつか取り上げられているのですが、その中にある「iBeaconと連携する勤怠管理アプリケーション」の項目に惹かれたのが理由です。
Beaconと呼ばれるBluetooth4.0以降に搭載されている*BLE(Bluetooth Low-Energy)*の技術を使った位置情報を特定できるデバイスを使った実装例があるとのことで、IoT技術に関心を寄せている私は早速サンプルコードを動かしてみようと取り掛かりました。

問題:サンプルコードが動かない

まあ予想はしてました。なんせ出版されたのが2016年なんですもの。
近年のコンピュータ技術は発展がものすごく早いので、少し前に出版された本のサンプルが動くだなんて期待してはいけません。
ということで少し現状を整理しながら原因を探っていくことにしました。

仕組み

このiBeaconを使ったサンプルの仕組みですが、ざっくり言えばBeaconを受信する勤怠アプリがBeaconを受信したらAPI経由でDynamoDB上に作成された勤怠情報を格納するようになっています。肝心のBeaconの発信側ですがnode-bleaconと呼ばれるライブラリを使うことでPCで代用できるようになっております。

調査

で、原因ですが、node-bleaconはNode.jsの現行バージョン(ver 14.x)に非対応だからでした。
node-bleaconblenoというライブラリをラップしたものなのですが、どうやらメンテがされておらずver9.xまでしか使えない様子でした。
代わりとなるライブラリを探してみたものの、node-beacon-scannerといった受信機能のあるものはありましたが、発信機能があるものはみつかりませんでした。
iBeaconを使ったサンプルなのにBeaconが発信できないとなると流石に困りました。
とは言え流石にサンプルを動かすためだけにラズパイやBeaconモジュールを買うわけにもいかず、すぐにでも試したかったので他の手段がないか探しました。

スマホを発信器として使う

よく考えてみたら受信端末として使おうとしているこのiPhoneを発信器として利用できるのではと思い、調べてみたらちゃんとできるようです。

公式ドキュメント:https://developer.apple.com/documentation/corelocation/turning_an_ios_device_into_an_ibeacon_device

Beaconで使われてるBLEの通信にはそれぞれ役割があり、受信側をCentral、発信側をPeripheralと呼ぶそうです。
というわけでサンプルコードを動かすためにまずはBeacon発信機能をiPhoneに実装することにしました。

実装

以下に作成したコードを載せておきます。
最小限の実装で済ませるため、ここではアプリを起動すると画面には何も表示されず、アプリを落とすまでBeaconを発信し続けるようにしております。

appDelegate.swift
import UIKit
import CoreLocation
import CoreBluetooth

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate, CBPeripheralManagerDelegate {
    
    var localBeacon : CLBeaconRegion!;
    var beaconPeripheralData: NSDictionary!;
    var peripheralManager: CBPeripheralManager!
    
    let BEACON_ID: String = "BEACON"
    let uuid: UUID = UUID(uuidString: "01234567-89AB-CDEF-0123-456789ABCDEF")! // 事前にuuidを用意しておく
    let MAJOR: CLBeaconMajorValue = 10
    let MINOR: CLBeaconMinorValue = 20
    
    // アプリケーションの起動完了後に実行される処理
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        self.initBeacon()
        return true
    }

    // Beaconを起動
    func initBeacon() {
        if localBeacon != nil {
            stopLocalBeacon()
        }
        localBeacon = createBeaconRegion()!

        beaconPeripheralData = localBeacon.peripheralData(withMeasuredPower: nil)
        peripheralManager = CBPeripheralManager(delegate: self, queue: nil, options: nil)
    }
    
    // Beaconを停止
    func stopLocalBeacon() {
        peripheralManager.stopAdvertising()
        peripheralManager = nil
        beaconPeripheralData = nil
        localBeacon = nil
    }
    
    // Bluetoothの電源が切り替わった際に実行される処理
    func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
        if peripheral.state == .poweredOn {
            peripheralManager.startAdvertising(beaconPeripheralData as? [String: Any])
        } else if peripheral.state == .poweredOff {
            peripheralManager.stopAdvertising()
        }
    }
    
    func createBeaconRegion() -> CLBeaconRegion? {
        return CLBeaconRegion(
            proximityUUID: self.uuid,
            major: self.MAJOR,
            minor: self.MINOR,
            identifier: self.BEACON_ID
        )
    }
    

動作確認

動作を確認するには先ほど作成したアプリ以外に、Beaconの受信機能とその端末が必要になります。最初の方に話したnode-beacon-scannerなどを使って開発することもできますが、そんな余裕はなかったのですでに出回っているもの、ここではBeacon Scanというアプリを使って確認することにします。なお端末は自分のiPadを使用しました。

アプリを起動するとこんな画面が出てきます。
IMG_0942.PNG

右下の設定アイコンをタップして発信側で設定しているUUIDを入力します。
IMG_0943.PNG

保存を押し、リスト画面に戻るとiPhoneから発信されているBeacon情報が確認できます。
IMG_0944.PNG

補足

・BeaconRegionを作成する際にUUIDが必要になります。ターミナルで

$ uuidgen

を実行してUUIDを作成してください。
また、majorminor情報も必要となります。これは識別情報のひとつでmajorはグループ(例:フロアや階層)、minorは個々(例:置かれている部屋や場所)を識別するために使います。Beaconが複数あったときにどれが発信しているものかわかるようにするためですね。

・この機能はBluetoothを使用するので、info.plistPrivacy - Bluetooth Always Usage Description(xlmファイルで開いている場合は<key>NSBluetoothAlwaysUsageDescription</key>)の設定をするようにしてください。これがないとアプリを実行することができません。

感想

最初はサンプルコードが動かず、Beacon発信器もないためあきらめかけていましたが、iPhoneに発信機能を実装することで引き続きサンプルを試すことができそうです。
常に感じていることですが、まだプログラミング経験の浅い初学者はサンプルコードが動く書籍を買うことをお勧めします。そのためにも書籍の発刊日やアップデートに対応しているをチェックしましょう。
なお不満が多く批判的に聞こえているかもしれませんが、本書はクラウドネイティブな構成に必要なサービスの知識及び例が豊富に含まれているので、私を含めて事故解決できるひとでデザインパターンを知りたい方にはおすすめです。

8
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?