在這篇文章中,我們將深入探討使用 Swift 實作藍牙應用的第一部分。我們將建立一個 BluetoothService
類別,作為我們應用中管理藍牙連接的核心。這個服務將負責掃描藍牙周邊設備、連接這些設備以及管理數據通信。
BluetoothService
類別利用 CoreBluetooth 框架的功能來與藍牙設備進行互動。以下是實作的內容:
import Foundation
import CoreBluetooth
class BluetoothService: NSObject {
static let shared = BluetoothService()
weak var delegate: BluetoothServiceDelegate?
var central: CBCentralManager?
var peripheral: CBPeripheralManager?
var connectedPeripheral: CBPeripheral?
var rxtxCharacteristic: CBCharacteristic?
private var bluePeripherals: [CBPeripheral] = []
// 初始化:副線程
private override init() {
super.init()
let queue = DispatchQueue.global()
central = CBCentralManager(delegate: self, queue: queue)
}
// 開始掃描藍牙裝置
func startScan() {
central?.scanForPeripherals(withServices: nil, options: nil)
}
// 停止掃描
func stopScan() {
central?.stopScan()
}
// 連接藍牙周邊設備
func connectPeripheral(peripheral: CBPeripheral) {
self.connectedPeripheral = peripheral
central?.connect(peripheral, options: nil)
}
// 中斷與藍牙周邊設備連接
func disconnectPeripheral(peripheral: CBPeripheral) {
central?.cancelPeripheralConnection(peripheral)
}
}
單例模式: 我們將 BluetoothService
實作為單例,使用靜態的 shared
實例,這樣可以方便地從應用的任何地方訪問服務。
CBCentralManager: 這是管理發現的藍牙設備的主要介面。我們在背景線程中初始化它,以確保性能流暢。
周邊設備管理: 此服務可以掃描周邊設備、連接選定的設備並在必要時中斷連接。
我們需要實作 CBCentralManagerDelegate
的方法,以處理藍牙狀態更新和發現設備的事件:
extension BluetoothService: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown:
print("unknown")
case .resetting:
print("resetting")
case .unsupported:
print("unsupported")
case .unauthorized:
print("unauthorized")
case .poweredOff:
print("poweredOff")
case .poweredOn:
print("poweredOn")
@unknown default:
print("藍牙裝置未知狀態")
}
startScan()
}
// 發現藍牙裝置
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
for newPeripheral in bluePeripherals {
if peripheral.name == newPeripheral.name {
return
}
}
if let name = peripheral.name {
bluePeripherals.append(peripheral)
print(name)
}
delegate?.getBLEPeripherals(peripherals: bluePeripherals)
}
// 連接到設備
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices(nil)
}
}
狀態更新: centralManagerDidUpdateState
方法響應藍牙狀態的變化。如果藍牙已開啟,則開始掃描周邊設備。
設備發現: didDiscover
方法過濾掉重複的周邊設備,並更新代理,提供已發現設備的列表。
一旦連接到周邊設備,下一步是發現其服務和特徵。我們可以通過實作 CBPeripheralDelegate
的方法來完成這一點:
extension BluetoothService: CBPeripheralDelegate {
// 發現服務
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: (any Error)?) {
if let service = peripheral.services {
for service in service {
print(service)
peripheral.discoverCharacteristics(nil, for: service)
}
}
}
// 發現特徵
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: (any Error)?) {
if let characteristics = service.characteristics {
for characteristic in characteristics {
print(characteristic)
if characteristic.uuid.isEqual(CBUUID(string: "FFE1")) {
peripheral.readValue(for: characteristic)
peripheral.setNotifyValue(true, for: characteristic)
rxtxCharacteristic = characteristic
}
}
}
}
// 特徵值更新
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: (any Error)?) {
guard characteristic == rxtxCharacteristic,
let characteristicValue = characteristic.value,
let ASCIIstring = String(data: characteristicValue, encoding: String.Encoding.utf8) else {
return
}
print(ASCIIstring)
delegate?.getBLEPeripheralsValue(value: ASCIIstring)
}
}
服務發現: didDiscoverServices
方法檢索連接的周邊設備提供的服務。
特徵管理: 在 didDiscoverCharacteristicsFor
中,我們檢查是否存在特定的特徵(UUID 為 "FFE1"),並設置該特徵為通知模式。
數據接收: didUpdateValueFor
方法用於檢索和處理來自周邊設備的數據。
在這部分的藍牙應用實作中,我們成功建立了一個 BluetoothService
類別,這為連接和互動藍牙設備奠定了基礎。通過管理中央管理器和周邊通信,我們現在可以基於這個服務進一步開發功能完善的藍牙應用。