CABTMIDILocalPeripheralViewControllerを使わずにMIDI over BLEでアドバータイズする方法
ワイヤレスMIDI接続をしてアプリから他の端末にMIDIデータを送信したい
CoreAudioKit の CABTMIDILocalPeripheralViewController を使うとiPhone(またはiPad)アプリ上に MIDI over Bluetooth LE のアドバータイズの設定画面を表示することができます。
上記画面の Advertise MIDI Service の項目をオンにするとアプリ側を BLE ペリフェラルとしてアドバータイズすることができます。
CABTMIDILocalPeripheralViewControllerを使わずにアドバータイズしたい
SwiftUI や SpriteKit で画面構築をしていると CABTMIDILocalPeripheralViewController のような UIViewController を継承したクラスを使うのは少し大変です。そこで CABTMIDILocalPeripheralViewController を使わずに直接 CoreBluetooth を使ってMIDI over BLE のアドバータイズができないか調べてみました。その結果サービスのIDとキャラクタリスティックのIDに特定の値を指定するとできることがわかりました。 以下は SpriteKit のシーンで BLE のアドバータイジングをするコードです。
import SpriteKit import CoreBluetooth class GameScene: SKScene { var manager: CBPeripheralManager! var service: CBMutableService! // MIDI Service UUID let serviceID = CBUUID(string: "03B80E5A-EDE8-4B33-A751-6CE34EC4C700") // MIDI I/O Characteristic UUID let characteristicID = CBUUID(string: "7772E5DB-3868-4112-A1A9-F2669D106BF3") override func didMove(to view: SKView) { super.didMove(to: view) self.manager = CBPeripheralManager(delegate : self, queue : nil, options: nil) } } extension GameScene: CBPeripheralManagerDelegate { // ペリフェラルの状態通知 func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { guard peripheral.state == .poweredOn else { print("error: \(peripheral.state)") return } print("bluetooth pwoer on") // サービスとキャラクタリスティックの追加 self.service = CBMutableService(type: self.serviceID, primary: true) let properties: CBCharacteristicProperties = [.notify, .read, .writeWithoutResponse] let permissions: CBAttributePermissions = [.readable, .writeable] let characteristic = CBMutableCharacteristic(type: self.characteristicID, properties: properties, value: nil, permissions: permissions) self.service.characteristics = [characteristic] self.manager.add(self.service) } // サービス追加の成功失敗通知 func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { guard (error == nil) else { print("Add service failed") return } print("Add service succeeded") // アドバタイズ開始 let advertisementData = [CBAdvertisementDataLocalNameKey: "Penguin Drums", CBAdvertisementDataServiceUUIDsKey: [self.serviceID]] as [String : Any] manager.startAdvertising(advertisementData) print("Service starts advertising!") } }
サービスのIDには 03B80E5A-EDE8-4B33-A751-6CE34EC4C700 をキャラクタリスティックのIDには 7772E5DB-3868-4112-A1A9-F2669D106BF3 を指定します。またキャラクタリスティックのプロパティに Read, Write, Notify を指定します。