Skip to content

Instantly share code, notes, and snippets.

@liuzhida33
Forked from huguesbr/ViewController.swift
Created December 20, 2018 05:53
Show Gist options
  • Select an option

  • Save liuzhida33/281ab1a3e7ee6aca4aa837fb1ae55a43 to your computer and use it in GitHub Desktop.

Select an option

Save liuzhida33/281ab1a3e7ee6aca4aa837fb1ae55a43 to your computer and use it in GitHub Desktop.

Revisions

  1. @huguesbr huguesbr created this gist Apr 5, 2017.
    115 changes: 115 additions & 0 deletions ViewController.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,115 @@
    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)
    }
    }