【问题标题】:iOS RxSwift 4.2 how to implement Reactive extension of CBCentralManager using DelegateProxy?iOS RxSwift 4.2 如何使用 DelegateProxy 实现 CBCentralManager 的 Reactive 扩展?
【发布时间】:2018-09-10 22:35:58
【问题描述】:

我正在查看this example of using reactive extensions with Core Bluetooth。但是,它是用 swift 3.0 编写的,并且在 Swift 4.2 中运行时存在许多错误。我有兴趣实现CBCentralManager 的响应式扩展,为我提供状态事件的 RX 流。

我的理解是,这允许代理从 CBCentralManager 接收委托事件并使用 _stateBehaviorSubject: BehaviorSubject<CBManagerState>? 将它们传播给观察者但是,该项目有太多错误,我无法弄清楚我应该在哪里削减以仅保留我的功能想。

如何使用 CBCentralManager 的 DelegateProxy 实现反应式扩展?

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)
  }
}

【问题讨论】:

标签: ios reactive-programming core-bluetooth rx-swift


【解决方案1】:

这是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)
   }
}

【讨论】:

  • 将 ControlEvent 与 BehaviorSubject 配对对我来说似乎有点奇怪。在我看来,var state: Observable&lt;CBManagerState&gt; { return stateBehaviorSubject.asObservable() } 是您在扩展程序中真正需要的。
  • 很好地将centralManagerDidUpdateState 中的呼叫转发到_forwardToDelegate,我在实施过程中错过了这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 2020-01-16
  • 2019-03-01
  • 1970-01-01
  • 2017-06-25
相关资源
最近更新 更多