LoginSignup
14
12

More than 5 years have passed since last update.

iOS同士でBLE通信を行う

Posted at

Introduction

iOS同士でBLE通信をする際のサンプルコードがあったが、その発火順番とその意味がよくわからなかったので、自分の理解を高めるためにもメモとして記すことにした。

用語の定義

Central

  • 接続する側
  • Advertiseを受けたあとに接続をし、あとはよしなにしてくれる

Peripheral

  • 接続される側。
  • Advertiseをする側。

ServiceUUID

  • 簡単にいうと、サービスの識別子のUUID
  • 複数のCharacteristicsUUDを持つことができる

CharacteristicUUID

  • Slack(ServiceUUID)に対するチャンネル(CharacteristicUUID)みたいなもの
  • 具体的な通信内容を含む。

具体的な手順

設定

  • Peripheralサイド
    • CBPeripheralManager を継承
    • peripheralManagerを初期化
    • peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) が発火するので、peripheral.state.poweredOn の時に peripheralManagerserviceUUIDcharacteristicUUID をセットする。
  • Centralサイド
    • CBCentralManagerCBPeripheralManager を継承
    • centralManager を初期化
    • centralManagerDidUpdateState(_ central: CBCentralManager) が発火するので、central.state.poweredOn の時に scanForPeripherals(withServices serviceUUIDs: [CBUUID]?, options: [String : Any]? = nil) を使い、advertiseを受信する。

発火順番

Peripheral アドバタイズの開始

  • 設定が終わるとperipheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) が発火する。
  • エラーがない場合、PeripheralManager.startAdvertising(_ advertisementData: [String : Any]?) を呼び周囲にアドバタイズを開始する

Central 対象ServiceUUIDがあるか調べる

  • advertiserを受けると、centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) が発火する。
  • その後、 CBPeripheral.discoverServices(_ serviceUUIDs: [CBUUID]?)を呼び、Central側が探しているサービスがあるのかどうかを調べる

Central 対象CharacteristicUUIDがあるか調べる

  • 対象 ServiceUUID がアドバタイズされていた場合、CBPeripheralDelegate.peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) が発火する。
  • service 内に狙っている characteristicUUID があるのかを調べるために、 CBPeripheral.discoverCharacteristics(_ characteristicUUIDs: [CBUUID]?, for service: CBService) を呼ぶ。

Central Characteristicからデータを読み取るリクエストを飛ばす

  • 対象characteristicがあった場合 peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) が発火する。
  • CBPeripheral.readValue(for characteristic: CBCharacteristic)を用いてデータの読み取りをリクエストする。

Peripheral レスポンスするデータを作成し、Centralに渡す

  • リクエストを受けると peripheralManager:(CBPeripheralManager *)peripheral didReceiveReadRequest:(CBATTRequest *)request が発火する。
  • request.value のデータを変えて、CBPeripheralManager.respond(to request: CBATTRequest, withResult result: CBATTError.Code) でデータを送り返す

Central データを読み取る

  • データが送られてくると、peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) が発火する。
  • characteristic.valueData 形式になっているので、適切な形に解析する。

以上。

14
12
0

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
14
12