原本是想來介紹一下 SwiftData 和 Macro,不過這裡還沒更新到可以操作這兩個的版本,所以先改成來介紹一下別的東西吧。
那麼接下來介紹一下關於藍牙的部分,首先在 Swift 中關於藍牙的函式都是在 CoreBluetooth 之中,所以在使用前需要先 import 進來。
import CoreBluetooth
接下來在正式開始之前要先來講解一下 CoreBluetooth 裡藍牙運作的方式,首先是藍牙裝置會被分成兩種:Central 跟 Peripheral,分別對應 App 端跟外部裝置,兩個分別處理的工作也不太一樣。
先來說 Central 的部分,也就是 App 端,主要的工作包含:掃描、連接外部藍牙裝置。
首先先指定一個變數,他的型別是 CBCentralManager,然後接下來,由於 BluetoothServices 這個檔案是在外部,我們需要寫一下這個 class 的啟動。
import Foundation
import CoreBluetooth
class BluetoothServices: NSObject {
var central: CBCentralManager?
private override init() {
super.init()
}
}
接下來是開始掃描、連接的部分,而 Central 工作的函式是由 CBCentralManagerDelegate 來處理,所以需要先 extension 進來。
extension 進來之後會報錯是正常的,因為它裡面有個函式是必須要呼叫的,按一下報錯訊息裡的 Fix,Xcode 會自己幫你加好。
extension BluetoothServices: CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
}
}
新增函式的功能主要是在 Central 啟動時執行,或是在 State 有改變的時候執行,這裡的 State 是指手機端藍牙的狀態,這裡會判斷 State 來列印出對應的文字。
extension BluetoothServices: 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("藍牙裝置未知狀態")
}
}
}
可以看到這裡藍牙裝置分為 6 種狀態,以及一種未知狀態。
到這裡都是啟動 Central 之後要做的事情,但是還沒決定什麼時候啟動,這裡由於我希望這個檔案啟動的時候也能同時啟動 Central,所以我們在上面已經寫好的 init 裡再多加一些東西。
private override init() {
super.init()
let quene = DispatchQueue.global()
central = CBCentralManager(delegate: self, queue: quene)
}
到這裡為止,才真正算是設定好 Central 的部分,接下來是 Central 的工作。
設定好之後,就是正式上工了。
首先,連接裝置之前需要知道有哪些外部裝置可以連接,這裡的程式很簡單,只需要一行就能讓 Central 開始掃描附近有哪些外部裝置可以連接。
central?.scanForPeripherals(withServices: nil)
接下來,又回到 CBCentralManagerDelegate 的部分,CBCentralManagerDelegate 裡有個函式是在 Central 發現裝置時執行的,我們需要在這裡去進行後續的處理。
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi RSSI: NSNumber) {
}
為了處理裝置,這裡先創建一個陣列用來儲存發現的外部裝置,然後在上面提到發現外部裝置時會執行的程式裡去處理。
private var blePeripherals: [CBPeripheral] = []
這裡每次執行時都會去判斷陣列裡有沒有這個外部裝置,如果沒有就會新增進去。
for newPeripheral in blePeripherals {
if peripheral.name == newPeripheral.name {
return
}
}
if let name = peripheral.name {
blePeripherals.append(peripheral)
print(name)
}
掃描的部分都完成了,接下來是連接的部分,連接也很簡單,只需要將你要連接的裝置作為參數傳入。
func connectPeripheral(peripheral: CBPeripheral) {
central?.connect(peripheral, options: nil)
}
但是這樣還沒完全處理完,連接的裝置有了,但是這裡沒有東西處理連接之後的工作,需要回到 CBCentralManagerDelegate 裡做最後一件事。
這裡會將裝置的處理代理給這個檔案,並且開始之後的工作。
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
peripheral.delegate = self
peripheral.discoverServices(nil)
}
那今天就先到這裡,明天來繼續處理 Peripheral 吧。