iOS 的藍牙開發主要是透過 CoreBluetooth 框架來實現的。
iOS 藍牙開發的關鍵概念
-
Centrals and Peripherals
- Centrals 中心設備 : 用來掃描周圍藍牙硬體的裝置, 比如使用手機的藍牙來掃描並連接智能手環, 這時候手機就是中心設備 。
- Peripherals 外部設備 : 被掃瞄的裝置。 以上面的例子智能手環就是外部設備。
-
Advertising Packets
- 外部設備會廣播藍牙訊號 (advertising packets) , 而中心設備的工作為掃描這些訊號, 並辨別出任何相關的外部設備, 可以與個別的裝置連結來取得更多的資訊。
-
Services and Characteristics
- services 服務: 外部設備廣播和運行時會有服務, 可以理解為一個功能模組, 中心設備可以讀取服務。 外部設備可以有多個服務。
- Characteristics 特徵: 在服務中的一個單位, 一個服務 service可以有多個特徵, 特徵會有一個值, 一般來說讀寫的數據就是這個值。
注意事項: Simulator不支援藍牙功能。
注意事項: 外部設備與中心設備版本, 需要兩隻蘋果裝置, 各一隻。
CoreBluetooth的外部設備版本
專案設置 : Swift4 + Xcode9
Step1. 導入 CoreBluetooth
import CoreBluetooth
Step2. 實現 CBPeripheralManagerDelegate
需要實現功能 peripheralManagerDidUpdateState , 並將對應的功能填入對應狀態變化的時候。
extension ViewController: CBPeripheralManagerDelegate { func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { switch peripheral.state { case .unknown: print("未知的") case .resetting: print("重置中" case .unsupported: print("未支持") case .unauthorized: print("未驗證") case .poweredOff: print("關閉") case .poweredOn: print("啟動") // 在此創建服務 、 廣播 setupServiceAndCharacteristics() self.peripheralManager?.startAdvertising([CBAdvertisementDataServiceUUIDsKey : [CBUUID.init(string: Service_UUID)]]) } } }
Step3. 創建服務 、 廣播
private func setupServiceAndCharacteristics() { let serviceID = CBUUID.init(string: Service_UUID) let service = CBMutableService.init(type: serviceID, primary: true) let characteristicID = CBUUID.init(string: Characteristic_UUID) let characteristic = CBMutableCharacteristic.init(type: characteristicID, properties: [.read, .write, .notify], value: nil, permissions: [.readable, .writeable]) service.characteristics = [characteristic] self.peripheralManager?.add(service) self.characteristic = characteristic }
Step4. 實現外部設備對應的Callback
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) { // 當中心設備讀取數據時的callback } func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { // 中心設備發送數據時, 接收數據並寫入textField }
這樣就完成最基本的外部設備的藍牙傳送、接收的功能了。
CoreBluetooth的中心裝置版本
步驟幾乎相同, 不同的是實現 CBCentralManagerDelegate 的協議, 如果需要也有廣播的功能, 可以在實現 CBPeripheralDelegate 協議。
extension ViewController: CBCentralManagerDelegate, CBPeripheralDelegate {}
實現下列的函式
/** 找到符合要求的外部設備 */ func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { self.peripheral = peripheral central.connect(peripheral, options: nil) } /** didConnect Success */ func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { self.centralManager?.stopScan() peripheral.delegate = self peripheral.discoverServices([CBUUID.init(string: Service_UUID)]) print("didConnect Success") }
當連接成功的時候會呼叫上面的函式。
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral)
為了省電, 當連接上外部設備後, 就讓中心設備停止掃描。
/** Find Characteristic */ func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { for characteristic: CBCharacteristic in service.characteristics! { print("外部設備中的特徵有:\(characteristic)") } self.characteristic = service.characteristics?.last // Read characteristic peripheral.readValue(for: self.characteristic!) // 訂閱 peripheral.setNotifyValue(true, for: self.characteristic!) }
// 外部設備發送數據時, 接收數據並寫入textField func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { let data = characteristic.value self.textField.text = String.init(data: data!, encoding: String.Encoding.utf8) }
這樣便完成藍芽中心裝置的基本設定了。
有些細節寫在專案裡, 就不一一寫入文章中了, 請大家下載專案自行玩看看, 就會更了解藍牙的運作模式。
[hf_form slug=”%e4%b8%8b%e8%bc%89%e7%af%84%e4%be%8b%e7%a8%8b%e5%bc%8f%e7%a2%bc-swift-corebluetooth-%e8%97%8d%e7%89%99%e9%96%8b%e7%99%bc”]
探索更多來自 懶泥陳的閱讀書房 的內容
訂閱後即可透過電子郵件收到最新文章。