1.匯入CoreBluetooth
2.建立結構與宣告需要物件與參數
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| struct DiscoveredItem { var peripheral: CBPeripheral! var lastRSSI = var lastSeenDate: Date! init(newPeripheral:CBPeripheral, RSSI:Int) { peripheral = newPeripheral lastRSSI = RSSI lastSeenDate = Date() } }
|
3.於class中加入代理,並且宣告cantralManager(這邊使用TableView來顯示資料)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class ViewController:UIViewController,CBCentralManagerDelegate,UITableViewDelegate,UITableViewDataSource { var cantralManager:CBCentralManager? var allItems = [String:DiscoveredItem]() let CYCLING_SPEED_AND_CADENCE_SERVICE_UUID:CBUUID = CBUUID(string:"1816") let HR_SERVICE_UUID:CBUUID = CBUUID(string:"180D")
let HR_CHARACTERISTIC_UUID:CBUUID = CBUUID(string:"2A37") var HR_Characteristic:CBCharacteristic? = nil }
|
4.於ViewDidLoad把cantralManage加入到主執行緒
1 2 3 4
| override func viewDidLoad() { super.viewDidLoad() centralManager = CBCentralManager(delegate: self, queue: nil) }
|
5.偵測Centrel的狀態
變數centralState拿來儲存狀態
1 2 3 4 5 6 7 8
| func centralManagerDidUpdateState (_ central: CBCentralManager) { guard central.state == .powerdOn else { let centralState = central.state.rawValue return } let centralState = central.state.rawValue print("目前狀態為\(centralState)") }
|
6.設定Scan,並啟動 (看需求決定,可以在ViewDidLoad或者一個按鈕中)
如果你還看不懂下面在幹嘛,你就複製然後寫成一個方法在ViewDidLoad呼叫
1 2 3 4 5 6 7
| let services = [CYCLING_SPEED_AND_CADENCE_SERVICE_UUID,HR_SERVICE_UUID]
let options = [CBCentralManagerScanOptionAllowDuplicatesKey:true]
centralManager?.scanForPeripherals(withServices: services, options: options)
|
7.當有設備被搜尋到的時候會觸發的方法,並有peripheral(設備)、advertisementData(設備參數)、訊號強弱等三個參數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { let existItem = allItems[peripheral.identifier.uuidString] let newItem = DiscoveredItem(newPeripheral: peripheral, RSSI: Int(RSSI)) allItems[peripheral.identifier.uuidString] = newItem let now = Date() var lastReloadDate: Date? if existItem == nil || lastReloadDate == nil || now.timeIntervalSince(lastReloadDate!) > 2.0 { lastReloadDate = now tableView.reloadData() } }
|
8.創建與設備連結的方法
1 2 3 4 5 6 7 8 9 10 11
| func startConnect(indexPatch:IndexPath) {
let allKeys = Array(allItems.keys)
let targerKey = allKeys[indexPatch.row]
let targetItem = allItems[targerKey]
centralManager?.connect(targetItem!.peripheral, options: nil) }
|
9.觸發與設備連結,這邊我們使用的是TableView的accessoryButtonTap,當然你也可以寫在didSelectRowAtIndexPath中。
1 2 3 4
| func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) { startConnect(indexPatch: indexPath) }
|
10.第9步按下accessoryButton後便會觸發didConnect peripheral這個代理
1 2 3 4 5 6 7 8 9 10
| func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { let name = peripheral.name ?? "UnKnow" peripheral.delegate = self peripheral.discoverServices(nil) centralManager?.stopScan() }
|
10.執行peripheral.discoverServices(nil)後,便會觸發didDiscoverServices的代理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { print("搜尋服務已經完成,共有\(peripheral.services)") guard error == nil else { centralManager?.cancelPeripheralConnection(peripheral) return } for service in peripheral.services ?? [] { if service.uuid == HR_SERVICE_UUID { peripheral.discoverCharacteristics(nil, for: service) } } }
|
11.執行peripheral.discoverCharacteristics(nil, for: service)後,便會觸發didDiscoverCharacteristicsFor service這個代理
1 2 3 4 5 6 7 8 9 10 11 12
| guard error == nil else { return } for characteristic in service.characteristic ?? [] { if (characteristic.uuid == HR_CHARACTERISTIC_UUID) { peripheral.setNotifyValue(true, for: characteristic) HR_Characteristic = characteristic } }
|
12.command+n建立一個新的Swift File 命名為「BinaryConvert」並加入以下程式碼
/這是一個Uint8的擴充/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| extension UInt8 { func toBitArray() -> [Bool] { var Result:[Bool] = [] Result.append(((self) & 0x01) == 1); Result.append(((self >> 1) & 0x01) == 1) Result.append(((self >> 2) & 0x01) == 1) Result.append(((self >> 3) & 0x01) == 1) Result.append(((self >> 4) & 0x01) == 1) Result.append(((self >> 5) & 0x01) == 1) Result.append(((self >> 6) & 0x01) == 1) Result.append(((self >> 7) & 0x01) == 1) return Result; } }
|
13.第11步中,註冊了一數據通知,只要有更新就把數值傳入並且呼叫didUpdateValueFor characteristic這個Delegate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { if let value = characteristic.value { if (characteristic == HR_Characteristic) { let HRFlag = value[0].toBitArray()[0] if HRFlag == true { let hr = binaryToType([value[1],value[2]], UInt16.self) print("UInt16...\(hr)") } else { let hr = binaryToType([value[1]], UInt8.self) print("UInt8...\(hr)") } } } }
|
※若以上的步驟都完整的執行完畢,應該個可以拿到心跳帶回報的心跳數據