Swift愛好会 Advent Calendar 2016 23日目　Swift3 Bluetoothライブラリーの紹介

こんにちは、iosフリーランスエンジニアの永田大祐と申します。
機械学習の技術を高めて、iosのモバイルに、機械学習を繋げるエンジニアになります。
よろしくお願いします。

#Swift愛好会
Swift愛好会23日目を担当させていただきます。僕とは関係ありませんが、昔々親戚のお祖父さんが天皇家の料理人をしていたという事で、この日の担当にさせてもらいました。Swift愛好会には、合宿に参加させていただいたり、登壇をさせていただき、感謝しています。

#なぜBluetoothか？
デバイス接続が、無線になるからです。Bluetoothだけではありませんが、今のうちにこのような知見を深めて、技術レベルを上げていきたいと考えています。

#参考文献
https://www.amazon.co.jp/iOS×BLE-Core-Bluetoothプログラミング-堤-修一/dp/4883379736

初めは通信の概念や方式などの詳細が記載されています。3章が超絶難しいです。　
3章でやばいと思ったところで、４章がObjective-cとSwiftで書かれているサンプルプログラミングがあります。大量にあります。
BLE通信をiosで実施する上での共通のメソッドが多数あるので、使い方を習得すれば、共通で使えるようになると思います。
初めに始めた方々は凄いと思いました。鉄の意志かと思いました。



<img width="401" alt="スクリーンショット 2016-12-21 午前0.48.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/0247ebf5-dc24-145c-adbc-5f4d92d4f4e2.png">


#Swift3Xcode8でBluetoothライブラリーの紹介
こちらがリンク先になります。
https://github.com/daisukenagata/BLEView

ライブラリーを使用すれば、これだけでBLE通信ができてしまいます。

<img width="597" alt="スクリーンショット 2016-12-20 午後11.03.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/42e5cab6-8f93-731e-c782-cb6f1b2890b0.png">


#[Cocoa Advent Calendar 2016 23日目openCVをiOS Swift3.0.1で活用する。](http://qiita.com/daisukenagata/items/88f41d9f0fe862e97975)
podsインストールの詳細はこちらに記載しましたので、合わせてお読み願います。

#仕様は?

Appleの既存のCoreBluetoothを使用。

###1.初回起動時にCBPeripheralManagerとCBCentralManagerを初期化
####CBPeripheralManagerペリフェラルとは発信する方式

ハード機器をつなげる周辺機器と使われている物です。iosでもハードに搭載されていて、プログラムコードを記述する事で、実行できます。

####CBCentralManagerセントラルとは受信する方式

ハード機器につなげる上で受信する方で、機器の中央部に搭載されています。


###2.centralManagerDidUpdateState(_ central:CBCentralManager){}メソッド
####DidUpdateStateします。ここで何か処理をしたい場合は、独自の実装ができます。こちらを実装しないとプロトコル設定でエラーが出ます。

###3.peripheralManagerDidUpdateState{}メソッド
####ペリフェラルマネージャの状態が変化すると呼ばれます。

BLE通信をする場合の認証に必要です。　
switch文で、poweredOn,poweredOffなどのメソッドが用意されています。

        switch peripheral.state {
        case .poweredOn:
            
            // サービス登録開始
            publishservice()
            
        default:
            break
        }

 
###4.func publishservice(){}
####サービスを作成します。

BLEで端末情報や状態などを通信するデータです。
CBMutableServiceというメソッドでCBUUIDという独自の文字列設定をします。

    let characteristicUUID = CBUUID(string: "45088E4B-B847-4E20-ACD7-0BEA181075C2")


認証系を実装したら、

    // キャラクタリスティックをサービスにセット
    service.characteristics = [characteristicCBC]

キャラクタリスティックはデータや情報のやり取り行う単位で、複数のキャラクタリスティックを用いて、サービスを提供します。


###5.func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) {}
サービス追加処理が完了すると呼ばれるので、アドバタイズ開始メソッドを実施します。


    // アドバタイズ開始メソッドを呼ぶ。
    startAdvertise()

アドバタイズメントデータとは、サービスの付加情報です。

    // アドバタイズ開始
    peripheralManager.startAdvertising(advertisementData)          


###6.func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {}
アドバタイズ開始処理が完了すると呼ばれます。

    ここでスキャン開始メソッドを実装します。
    self.centralManager.scanForPeripherals(withServices: [serviceUUID], options: nil)


###7.func centralManager(_central:CBCentralManager,didDiscover peripheral: CBPeripheral,advertisementData: [String : Any],rssi RSSI: NSNumber) {
####Swift3からメソッドが新しくなりました。
常に動作してperipheralを探し続けます。peripheralを検出できましたら、自分の場合はalertControllerで接続をユーザーが選択する仕様にしました。内部的に自動接続する対応でも良いかもしれません。


###8.func pushStart(){} 
    接続開始
    self.centralManager.connect(peripheral, options: option)

###9. func centralManager(_ central:CBCentralManager,peripheral:CBPeripheral,error: NSError!){

####接続失敗時に呼ばれます。
ここで再接続の処理やエラーハンドリングの実装を行えばリカバリー可能です。


###10.func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {}
通信リクエスト受信時に呼ばれる
こちらで文字列を変換させたり、仕様によって実施できる作業があると思います。
自分の場合は通信している端末より、文字列を受け取り、音声に変換させました。

###11.public func peripheral(_ peripheral: CBPeripheral,didWriteValueFor characteristic:CBCharacteristic,error: Error?){}
通信が成功したかどうかを判定できます。ここでもエラーハンドリングで再度取得など対応ができると思います。

###12.func peripheral(_ peripheral: CBPeripheral,didUpdateValueFor characteristic: CBCharacteristic,error: Error?) {
今回は使用していませんが、書き込み時の判定ができます。

###以上が主な仕様になります。


#BLEライブラリーの通信設計図
<img width="512" alt="スクリーンショット 2016-12-22 午後8.08.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/131469/8c52d1d5-9721-6ce1-fdfc-f26946448b85.png">






#今後の目標
今年の最後にはBluetooth案件の業務に携わり、長年のメーカー経験のあるCTOの方のアーキテクチャはさすがだなと感動しました。

Bluetooth開発を自らも技術を高めていく上で、品質を高める。アーキテクチャを高いレベルで構築していき、安定したアプリケーションを構築していきたいと思います。

現在のライブラリーは、機能として、繋いで、通信をするだけなので、アーキテクチャも高めて通信周りのアップデートを重ねていきたいと思います。