SwiftyBluetooth 5.0

SwiftyBluetooth 5.0

测试已测试
语言语言 SwiftSwift
许可证 MIT
发布版上次发布2020年9月
SPM支持 SPM

Jordane belanger 维护。



  • 作者
  • Jordane Belanger

SwiftyBluetooth

基于闭包的 CoreBluetooth API。

特性

  • 替换每个 CBCentralManagerCBPeripheral 操作的基于代理的接口为基于闭包的接口。
  • CBCentralManager 状态变化和状态恢复的通知。
  • CBPeripheral 名称更新、特征值更新和服务更新的事件通知。
  • 每次蓝牙操作都有精确的错误和保证的超时。
  • 如果需要,将自动连接到 CBPeripheral 并尝试发现进行读取或写入操作所需的 BLE 服务和特征。

使用方法

库中有2个重要的类

  • Central类,是一个围绕CBCentralManager的单例包装器,用于通过闭包回调扫描外围设备并恢复之前的会话。
  • Peripheral类,是一个围绕CBPeripheral的包装器,用于通过闭包回调调用CBPeripheral函数。

以下是几个可能对你感兴趣的操作示例。

扫描外围设备

通过调用scanWithTimeout(...)并传递以秒为单位的timeoutcallback闭包来扫描外围设备,该闭包关闭以接收Peripheral结果回调以及扫描状态的更新

// You can pass in nil if you want to discover all Peripherals
SwiftyBluetooth.scanForPeripherals(withServiceUUIDs: nil, timeoutAfter: 15) { scanResult in
    switch scanResult {
        case .scanStarted:
            // The scan started meaning CBCentralManager scanForPeripherals(...) was called 
        case .scanResult(let peripheral, let advertisementData, let RSSI):
            // A peripheral was found, your closure may be called multiple time with a .ScanResult enum case.
            // You can save that peripheral for future use, or call some of its functions directly in this closure.
        case .scanStopped(let error):
            // The scan stopped, an error is passed if the scan stopped unexpectedly
    }
}        

注意,回调闭包可以被调用多次,但总是从包含.scanStarted.scanStopped结果的回调开始和结束。对于扫描期间找到的每个唯一的外围设备,您的回调都将被调用,以.scanResult的形式。

连接外围设备

peripheral.connect { result in 
    switch result {
    case .success:
        break // You are now connected to the peripheral
    case .failure(let error):
        break // An error happened while connecting
    }
}

从外围设备的服务特征读取

如果您已知要读取的特征和服务UUID,则一旦找到外围设备,就可以立即按照以下方式从它那里读取

peripheral.readValue(ofCharacWithUUID: "2A29", fromServiceWithUUID: "180A") { result in
    switch result {
    case .success(let data):
        break // The data was read and is returned as an NSData instance
    case .failure(let error):
        break // An error happened while attempting to read the data
    }
}

这将根据需要连接到外围设备,并确保在从匹配characteristicUUID的特征读取之前发现所需的特征和服务。如果无法检索特征/服务,您将收到一个指定哪一个特征/服务找不到的错误。

如果有一个对CBCharacteristic的引用,您可以直接使用该特征读取

peripheral.readValue(ofCharac: charac) { result in
    switch result {
    case .success(let data):
        break // The data was read and is returned as a Data instance
    case .failure(let error):
        break // An error happened while attempting to read the data
    }
}

向外围设备服务的特征写入

如果您已知想要写入的特征和服务的UUID,一旦找到外围设备,就可以直接像这样向该特征写入:

let data = String(0b1010).dataUsingEncoding(NSUTF8StringEncoding)!
peripheral.writeValue(ofCharacWithUUID: "1d5bc11d-e28c-4157-a7be-d8b742a013d8", 
                      fromServiceWithUUID: "4011e369-5981-4dae-b686-619dc656c7ba", 
                      value: data) { result in
    switch result {
    case .success:
        break // The write was succesful.
    case .failure(let error):
        break // An error happened while writting the data.
    }
}

接收特征更新通知

通过默认的NotificationCenter上的通知接收特征值更新。所有支持的Peripheral通知都是PeripheralEvent枚举的一部分。注册通知时,请使用此枚举的原始值作为通知字符串。

// First we prepare ourselves to receive update notifications 
let peripheral = somePeripheral

NotificationCenter.default.addObserver(forName: Peripheral.PeripheralCharacteristicValueUpdate, 
                                        object: peripheral, 
                                        queue: nil) { (notification) in
    let charac = notification.userInfo!["characteristic"] as! CBCharacteristic
    if let error = notification.userInfo?["error"] as? SBError {
        // Deal with error
    }
}

// We can then set a characteristic's notification value to true and start receiving updates to that characteristic
peripheral.setNotifyValue(toEnabled: true, forCharacWithUUID: "2A29", ofServiceWithUUID: "180A") { (isNotifying, error) in
    // If there were no errors, you will now receive Notifications when that characteristic value gets updated.
}

发现服务

使用discoverServices(...)函数发现服务

peripheral.discoverServices(withUUIDs: nil) { result in
    switch result {
    case .success(let services):
        break // An array containing all the services requested
    case .failure(let error):
        break // A connection error or an array containing the UUIDs of the services that we're not found
    }
}

与CBPeripheral的discoverServices(...)函数类似,传递nil而不是服务UUID数组将从该外围设备发现所有服务。

发现特征

使用discoverCharacteristics(...)函数发现特征。如果您尝试从尚未发现的服务发现特征,将会先为您发现该服务。

peripheral.discoverCharacteristics(withUUIDs: nil, ofServiceWithUUID: "180A") { result in
    // The characteristics discovered or an error if something went wrong.
    switch result {
    case .success(let services):
        break // An array containing all the characs requested.
    case .failure(let error):
        break // A connection error or an array containing the UUIDs of the charac/services that we're not found.
    }
}

与CBPeripheral的discoverCharacteristics(...)函数类似,传递nil而不是服务UUID数组将从该服务发现所有特征。

状态保存

SwiftyBluetooth由CBCentralManager单例包装支持,并且不会直接为您提供对底层CBCentralManager的直接访问。

但是,您仍然可以通过调用setSharedCentralInstanceWith(restoreIdentifier: )来设置底层CBCentralManager以恢复状态,并可以使用您选择的恢复标识符。

请注意,此方法只能调用一次,并且必须在初始化库中的任何其他内容之前调用,否则第一次访问它时将触发Central sharedInstance的懒加载。

因此,建议在您的App Delegate的didFinishLaunchingWithOptions(:)中调用它

SwiftyBluetooth.setSharedCentralInstanceWith(restoreIdentifier: "MY_APP_BLUETOOTH_STATE_RESTORE_IDENTIFIER")

在默认NotificationCenter上注册状态保存通知。这些通知将包含一个包含已恢复Peripheral的数组。

NotificationCenter.default.addObserver(forName: Central.CentralManagerWillRestoreStateNotification,
                                        object: Central.sharedInstance, 
                                         queue: nil) { (notification) in
    if let restoredPeripherals = notification.userInfo?["peripherals"] as? [Peripheral] {

    }
}

安装

CocoaPods

将其添加到您的Podfile中

pod 'SwiftyBluetooth', '~> 3.0.0'

Swift Package Manager

将库作为“包依赖项”简单地添加到您的xcode项目中

Carthage

将此添加到您的 Cartfile

github "jordanebelanger/SwiftyBluetooth"

需求

SwiftyBluetooth 需要 iOS 10.0 及以上版本

许可

SwiftyBluetooth 在 MIT 许可下发布。