iPhoneとBluetoothデバイスをScanするところをできるだけ簡単にやってみました。
Xcode 11.4
CoreBluetooth
Bluetooth といえば以前は消費電力が大きく、バッテリー消費の最適化として真っ先に停止されていたのですが Bluetooth version 4.0から低消費電力仕様となりBLEと通称されています。ただBluetooth Classicとは互換性がないので両方の機能を別に持つ必要があり面倒ではあります。
既にBLEから10年以上が経過しているのでClassicのことは忘れましょう(忘れたい)
iOSでBluetoothを扱うには Core Bluetooth を使います。
こちらのドキュメントがAppleから出ています。
Core Bluetooth Programming Guide あわせてこちらも参考にしました。
Transferring Data Between Bluetooth Low Energy Devices
用語
ここで使う使うBLEの主だった用語について
Central と Peripheral:
ネットワークのクライアント・サーバーの役割
Advertising:
Peripheralが名前や主要なサービス機能などの情報を周囲に発信する。その情報をいれたパケットが Advertising Packet でCentralで受け取る
UUID:
重複しない一意のIDで、サービスなどの個別機能を特定できます
Peripheral UUID
Service UUID
Characteristic UUID
- Peripheral
- Service1
- Characteristic1
- Characteristic2
- …
- Service2
- Service3
- …
- Service1
設定
最初に、info.plistに以下の記述をしてユーザーの許可をとるようにします。
NSBluetoothAlwaysUsageDescription
NSBluetoothPeripheralUsageDescription
info.plist
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> ... <key>NSBluetoothAlwaysUsageDescription</key> <string>Application uses Bluetooth</string> <key>NSBluetoothPeripheralUsageDescription</key> <string>Application uses Bluetooth connection</string> ... </dict> </plist> |
コーディングはこのような流れになります
- CentralManager 初期化
- CentralManager のstatus確認
- 検索開始
- Peripheral探索結果を受信
- 検索終了
サンプルコード
わかりやすく簡略化して、scanで周囲のPeripheralを探してみます。
ViewController.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
import UIKit import CoreBluetooth class ViewController: UIViewController, CBCentralManagerDelegate { var centralManager: CBCentralManager! override func viewDidLoad() { // CentralManager 初期化 centralManager = CBCentralManager(delegate: self, queue: nil, options: nil) super.viewDidLoad() } override func viewWillDisappear(_ animated: Bool) { centralManager.stopScan() print("Scanning stopped") super.viewWillDisappear(animated) } // CentralManager status func centralManagerDidUpdateState(_ central: CBCentralManager) { switch central.state { case .poweredOn: print("CBManager is powered on") startScan() case .poweredOff: print("CBManager is not powered on") return case .resetting: print("CBManager is resetting") case .unauthorized: print("Unexpected authorization") return case .unknown: print("CBManager state is unknown") return case .unsupported: print("Bluetooth is not supported on this device") return @unknown default: print("A previously unknown central manager state occurred") return } } // begin to scan func startScan(){ print("begin to scan ...") centralManager.scanForPeripherals(withServices: nil) } // stop scan func stopBluetoothScan() { self.centralManager.stopScan() } // Peripheral探索結果を受信 func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) { print("pheripheral.name: \(String(describing: peripheral.name))") print("advertisementData:\(advertisementData)") print("RSSI: \(RSSI)") print("peripheral.identifier.uuidString: \(peripheral.identifier.uuidString)\n") } } |
これで起動後にBluetoothがオンになっていればログが取れます。
デバイスのBluetooth設定がオフの場合、初期化でoptionを使うと設定画面に誘導してくれます。
1 2 3 |
CBCentralManager(delegate: self, queue: nil, options: [CBCentralManagerOptionShowPowerAlertKey: true]) |
References:
Core Bluetooth | Apple Developer Documentation
Core Bluetooth Programming Guide – Apple Developer
Transferring Data Between Bluetooth Low Energy Devices
BLE Docs