首页 > 解决方案 > iOS RxSwift 4.2 how to implement Reactive extension of CBCentralManager using DelegateProxy?

问题描述

I'm looking at this example of using reactive extensions with Core Bluetooth. However, it is written in swift 3.0 and has a number of errors running in Swift 4.2. I'm interested in implementing a reactive extension of CBCentralManager to provide me with a RX stream of status events.

My understanding is that this allows the proxy to receive delegate events from the CBCentralManager and propagate them to observers using _stateBehaviorSubject: BehaviorSubject<CBManagerState>? However, the project has too many errors and I cannot figure out where do I cut to keep only the functionality I want.

How do I implement the a reactive extension using DelegateProxy for CBCentralManager?

extension Reactive where Base: CBCentralManager {

  public var delegate: DelegateProxy {
    return RxCBCentralManagerDelegateProxy.proxyForObject(base)
  }

  public var state: Observable<CBManagerState> {
    let proxy = RxCBCentralManagerDelegateProxy.proxyForObject(base) //error here
    return proxy.stateBehaviorSubject.skip(1)
  }
}

标签: iosreactive-programmingcore-bluetoothrx-swift

解决方案


这是一个有效的实现CBCentralManager

extension CBCentralManager : HasDelegate {
    public typealias Delegate = CBCentralManagerDelegate
}

class RxCBCentralManagerDelegateProxy
  : DelegateProxy<CBCentralManager, CBCentralManagerDelegate>
  , DelegateProxyType
  , CBCentralManagerDelegate
{

   internal let stateBehaviorSubject: BehaviorSubject<CBManagerState>

   init(centralManager: CBCentralManager) {
       let subject = BehaviorSubject(value: centralManager.state)
       stateBehaviorSubject = subject

       super.init(parentObject: centralManager, delegateProxy: RxCBCentralManagerDelegateProxy.self)
   }

   func centralManagerDidUpdateState(_ central: CBCentralManager) {
       stateBehaviorSubject.onNext(central.state)
       _forwardToDelegate?.centralManagerDidUpdateState(central)
   }

   static func registerKnownImplementations() {
       self.register { RxCBCentralManagerDelegateProxy(centralManager: $0) }
   }

   deinit {
       stateBehaviorSubject.on(.completed)
   }
}

extension Reactive where Base : CBCentralManager {
   var delegate: DelegateProxy<CBCentralManager, CBCentralManagerDelegate> {
       return RxCBCentralManagerDelegateProxy.proxy(for: base)
   }

   var state: ControlEvent<CBManagerState> {
       let source = (delegate as! RxCBCentralManagerDelegateProxy)
          .stateBehaviorSubject
          .skip(1)
       return ControlEvent(events: source)
   }
}

推荐阅读