首先实现扫描性能,
1: 定义扫描接口,定义接口次要是升高耦合(实现该接口能够很轻松的重构扫描模块)
1:ScanBuilder 扫描构建器,形容创立扫描类须要的参数,以及返回对应的扫描器实例。
2:只有一个函数 scan ,返回值为 Observable
protocol BluetoothScanable { var scanInfo: (scanPrefix: [String], services: [CBUUID]) { get } var centralManager : CBCentralManager { get } typealias Input = ( centralManager: CBCentralManager, scanInfo: (scanPrefix: [String], services: [CBUUID]) ) typealias ScanBuilder = (BluetoothScanable.Input) -> BluetoothScanable func scan(duration: Int) -> Observable<(state: ScanState, response : [ScanResponse]?)>}public class ScanResponse { var peripheral: CBPeripheral var advertisementData: [String : Any]? var rssi: NSNumber init(peripheral: CBPeripheral, advertisementData: [String : Any]? = nil, rssi: NSNumber = NSNumber.init(value: 0)) { self.peripheral = peripheral self.advertisementData = advertisementData self.rssi = rssi }}复制代码复制代码
2: 扫描实现类
实现 BluetoothScanable 接口, 扫描的后果通过 信号的形式回传。
class BluetoothScan: BluetoothScanable { var scanInfo: (scanPrefix: [String], services: [CBUUID]) var centralManager: CBCentralManager init(centralManager: CBCentralManager, scanInfo: (scanPrefix: [String], services: [CBUUID])) { self.centralManager = centralManager self.scanInfo = scanInfo } func scan(duration: Int) -> Observable<(state: ScanState, response : [ScanResponse]?)> { // 返回 Observable return Observable<(state: ScanState, response : [ScanResponse]?)>.create { [centralManager, scanInfo] (subscriber) -> Disposable in if centralManager.state == .poweredOn { // 获取已连贯 var connected = centralManager.retrieveConnectedPeripherals(withServices: scanInfo.services) // 扫描前缀过滤 connected = connected.filter({ p in return (scanInfo.scanPrefix.filter({(p.name?.hasPrefix($0) ?? false)}).count) > 0 }) // 转为 ScanResponse 对象 let scanResponses = connected.map({ ScanResponse(peripheral: $0) }) if scanResponses.count > 0 { subscriber.onNext((state: .nomal, response: scanResponses)) } // 订阅扫描后果 ,接管信号发送过去的扫描后果 _ = centralManager.rx.didDiscoverPeripheral.filter({ p in return (scanInfo.scanPrefix.filter({ (p.peripheral.name?.hasPrefix($0) ?? false) }).count) > 0 }).subscribe(onNext: { (response) in //信号发送给订阅者 subscriber.onNext((state: .nomal, response: [response])) }) // 开始扫描 if UIApplication.shared.applicationState == .background { centralManager.scanForPeripherals(withServices: scanInfo.services , options: nil) } else { centralManager.scanForPeripherals(withServices: nil, options: nil) } // 指定工夫进行扫描 DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(duration)) { //完结发送给订阅者 centralManager.stopScan() subscriber.onNext((state: .end, response: [])) subscriber.onCompleted() } } else { subscriber.onError(ScanError.error(messae: "Bluetooth state error")) } return Disposables.create() } }}复制代码复制代码
3 : 扫描后果订阅的实现
CBCentralManager 扩大rx属性 , 间接返回 RxCBCentralManagerDelegateProxy 对象中的PublishSubject 属性。 内部订阅 rx 属性即可收到扫描后果信号。
extension Reactive where Base: CBCentralManager { public var delegate: DelegateProxy<CBCentralManager, CBCentralManagerDelegate> { return RxCBCentralManagerDelegateProxy.proxy(for: base) } public var didUpdateState: Observable<CBManagerState> { return RxCBCentralManagerDelegateProxy.proxy(for: base) .didUpdateStateSubject .asObservable() } public var didDiscoverPeripheral: Observable<ScanResponse> { return RxCBCentralManagerDelegateProxy.proxy(for: base) .didDiscoverPeripheralSubject .asObservable() } public var didConectPeripheral: Observable<ScanResponse> { return RxCBCentralManagerDelegateProxy.proxy(for: base) .didConnectPeripheralSubject .asObservable() } public var didFailToConnectPeripheral: Observable<ScanResponse> { return RxCBCentralManagerDelegateProxy.proxy(for: base) .didFailToConnectPeripheralSubject .asObservable() } public var didDisconnectPeripheral: Observable<ScanResponse> { return RxCBCentralManagerDelegateProxy.proxy(for: base) .didDisconnectPeripheralSubject .asObservable() }}class RxCBCentralManagerDelegateProxy: DelegateProxy<CBCentralManager, CBCentralManagerDelegate>, DelegateProxyType, CBCentralManagerDelegate { // 零碎代理会掉时,用于发送信号, 任何想晓得扫描后果的都能够订阅 var didUpdateStateSubject = PublishSubject<CBManagerState>() var didDiscoverPeripheralSubject = PublishSubject<ScanResponse>() var didConnectPeripheralSubject = PublishSubject<ScanResponse>() var didFailToConnectPeripheralSubject = PublishSubject<ScanResponse>() var didDisconnectPeripheralSubject = PublishSubject<ScanResponse>() init(_ centerManager: CBCentralManager) { super.init(parentObject: centerManager, delegateProxy: RxCBCentralManagerDelegateProxy.self) } /// 注册代理的实现为 RxCBCentralManagerDelegateProxy 实例 static func registerKnownImplementations() { self.register { RxCBCentralManagerDelegateProxy($0) } } static func currentDelegate(for object: CBCentralManager) -> CBCentralManagerDelegate? { return object.delegate } static func setCurrentDelegate(_ delegate: CBCentralManagerDelegate?, to object: CBCentralManager) { object.delegate = delegate } func centralManagerDidUpdateState(_ central: CBCentralManager) { _forwardToDelegate?.centralManagerDidUpdateState(central) /// 当代理回调 蓝牙状态发生变化 发送信号给订阅者 didUpdateStateSubject.onNext(central.state) } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { didDiscoverPeripheralSubject.onNext(ScanResponse(peripheral: peripheral, advertisementData: advertisementData, rssi: RSSI)) } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { didConnectPeripheralSubject.onNext(ScanResponse(peripheral: peripheral)) } func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) { didFailToConnectPeripheralSubject.onNext(ScanResponse(peripheral: peripheral)) } func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) { didDisconnectPeripheralSubject.onNext(ScanResponse(peripheral: peripheral)) } }复制代码复制代码
4 : 具体应用
1: 在 didFinishLaunchingWithOptions 中 先配置 BleFacade (初始化蓝牙)提供要连贯的设施名或扫描的前缀以及服务特色,配置BleFacade 中应用的设施扫描器 和 设施连接器。 所有蓝牙操作都通过BleFacade类执行。
// 连贯 的具体实现类, 扫描器的Builer 会传入 centralManager 和 scanInfo let scanBuilder: BluetoothScanable.ScanBuilder = { BluetoothScan(centralManager: $0.centralManager, scanInfo: $0.scanInfo) } // 连贯 的具体实现类, 扫描器的Builer 会传入 centralManager 和 scanInfo 以及 scaner let connectBuilder: BluetoothConnectable.ConnectBuilder = { BluetoothConnect( centralManager: $0.centralManager, connectInfo: $0.connectInfo, scaner: $0.scaner ) } // 扫描 和 连贯 的配置 let services = [CBUUID.init(string: "service uuid1"), CBUUID.init(string: "service uuid2")] let config = BleDeviceConfig("DeviceName", ["DeviceNamePrefix"], services) BleFacade.shared.config(config, scanBuilder, connectBuilder)复制代码复制代码
// 在须要扫描的中央 执行扫描操作即可
func clicnScanBtn(_ sender: Any) { BleFacade.shared.scaner.scan(duration: 3) .subscribe(onNext: { (state, response) in if state == .nomal { response?.filter({ $0.peripheral.name != nil }).forEach({ (res) in print("per name: (String(describing: res.peripheral.name))") }) } else if (state == .end) { print("扫描完结") } }, onError: { error in print("(error)") }).disposed(by: bag) }复制代码复制代码
结束语;如对RxSwift感兴趣的能够;563513413,不论你是大牛还是小白都欢送入驻。大家能够相互交流学习................