Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Sample RxBluetoothKit implementation
import UIKit
import CoreBluetooth
import RxSwift
import RxBluetoothKit
extension CBUUID {
var type: UUID {
return UUID(rawValue: uuidString)!
}
enum UUID: String {
case main = "3749FA00-4CED-524B-33D5-F00FD858C4F2"
case info = "3749FA01-4CED-524B-33D5-F00FD858C4F2"
case alert = "3749FA05-4CED-524B-33D5-F00FD858C4F2"
var cbuuid: CBUUID { return CBUUID(string: self.rawValue) }
}
static func common(_ type: UUID) -> CBUUID {
return type.cbuuid
}
}
extension ObservableType {
func unwrap() -> Observable<E> {
return flatMap { $0 == nil ? Observable.empty() : Observable.just($0!) }
}
}
extension ObservableType {
public func retryWithDelay(_ timeInterval: RxTimeInterval, maxAttempts: Int? = nil)
-> Observable<E> {
return retryWhen { (errors: Observable<Error>) in
return errors.flatMapWithIndex { (error, attempt) -> Observable<Int64> in
if let maxAttempts = maxAttempts, attempt >= maxAttempts - 1 {
return Observable.error(error)
}
return Observable<Int64>.timer(timeInterval, scheduler: MainScheduler.instance)
}
}
}
}
class Device {
let measure = PublishSubject<Data>()
let alert = PublishSubject<Data>()
private let disposeBag = DisposeBag()
init(name: String) {
let manager = BluetoothManager(queue: .main)
let queue = DispatchQueue(label: "fr.xdev.rxbluetoothkit.bluetooth")
let scheduler = SerialDispatchQueueScheduler(queue: queue, internalSerialQueueName: "")
let characteristics = manager.rx_state
.filter { $0 == .poweredOn }
.take(1)
.flatMap { _ in manager.scanForPeripherals(withServices: [.common(.main)]) } // scan
.filter { $0.peripheral.name == name }
.take(1)
.flatMap { $0.peripheral.connect() }
.flatMap { $0.discoverServices([.common(.main)]) } // extension on CBUUID to matching enum
.flatMap { Observable.from($0) }
.flatMap { $0.discoverCharacteristics([.common(.measure), .common(.protection)]) } // extension on CBUUID to matching enum
.flatMap { Observable.from($0) }
characteristics
.filter { $0.uuid.type == .measure } // extension on CBUUID to matching enum
.flatMap { $0.setNotificationAndMonitorUpdates() }
.map { $0.value }
.unwrap() // ignore nil value
.retryWithDelay(5) // !!!: retry and resubscribe to the full chain on error
.subscribe(onNext: { [unowned self] data in
self.measure.onNext(data!)
})
.disposed(by: disposeBag)
characteristics
.filter { $0.uuid.type == .alert } // extension on CBUUID to matching enum
.flatMap { $0.setNotificationAndMonitorUpdates() }
.map { $0.value }
.unwrap() // ignore nil value
.retryWithDelay(5) // !!!: retry and resubscribe to the full chain on error
.subscribe(onNext: { [unowned self] data in
self.alert.onNext(data!)
})
.disposed(by: disposeBag)
}
}
class ViewController: UIViewController {
let disposeBag = DisposeBag()
let device = Device(name: "Device-XXX")
override func viewDidLoad() {
super.viewDidLoad()
device.measure
.subscribeOn(MainScheduler.instance)
.subscribe(onNext: { data in
print("measure:", [UInt8](data))
})
.disposed(by: disposeBag)
device.alert
.subscribeOn(MainScheduler.instance)
.subscribe(onNext: { data in
print("alert:", [UInt8](data))
})
.disposed(by: disposeBag)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.