这正是受试者擅长做的事情。它们主要用于将非RX代码转换为RX代码。也就是说,Rxcococa有
DelegateProxy
设计用于处理大量必要工作以正确处理委托的类型。很难弄清楚如何实现一个,但是一旦你掌握了它的窍门,它们就非常有用了…
我不得不承认,大多数代码对我来说都是黑色的魔法,但它确实有效。我尽量在下面的评论中解释。
import RxSwift
import RxCocoa
import CoreBluetooth
extension CBPeripheralManager: HasDelegate {
public typealias Delegate = CBPeripheralManagerDelegate
}
class CBPeripheralManagerDelegateProxy
: DelegateProxy<CBPeripheralManager, CBPeripheralManagerDelegate>
, DelegateProxyType
, CBPeripheralManagerDelegate {
init(parentObject: CBPeripheralManager) {
super.init(parentObject: parentObject, delegateProxy: CBPeripheralManagerDelegateProxy.self)
}
deinit {
_didUpdateState.onCompleted()
}
static func registerKnownImplementations() {
register { CBPeripheralManagerDelegateProxy(parentObject: $0) }
}
static func currentDelegate(for object: CBPeripheralManager) -> CBPeripheralManagerDelegate? {
return object.delegate
}
static func setCurrentDelegate(_ delegate: CBPeripheralManagerDelegate?, to object: CBPeripheralManager) {
object.delegate = delegate
}
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) {
_didUpdateState.onNext(peripheral.state)
}
fileprivate let _didUpdateState = PublishSubject<CBManagerState>()
}
extension Reactive where Base: CBPeripheralManager {
var delegate: CBPeripheralManagerDelegateProxy {
return CBPeripheralManagerDelegateProxy.proxy(for: base)
}
var state: Observable<CBManagerState> {
return delegate._didUpdateState
}
var didUpdateState: Observable<Void> {
return delegate._didUpdateState.map { _ in }
}
var willRestoreState: Observable<[String: Any]> {
return delegate.methodInvoked(#selector(CBPeripheralManagerDelegate.peripheralManager(_:willRestoreState:)))
.map { $0[1] as! [String: Any] }
}
var didStartAdvertising: Observable<Error?> {
return delegate.methodInvoked(#selector(CBPeripheralManagerDelegate.peripheralManagerDidStartAdvertising(_:error:)))
.map { $0[1] as? Error }
}
}
据我所知,
methodInvoked
函数对对象执行一些元编程魔术,以便在运行时安装该方法。之所以这样做,是因为许多具有委托的IOS类实际上行为不同,这取决于该方法是否在委托上定义(不管该方法做什么),因此我们不希望简单地将协议中的每个方法都给代理。
当然,一旦你有了上面的内容。您可以使用外围设备管理器执行所有标准的Rx操作:
bluetoothManager.rx.state
.subscribe(onNext: { state in print("current state:", state) })
.disposed(by: disposeBag)
bluetoothManager.rx.didStartAdvertising
.subscribe(onNext: { error in
if let error = error {
print("there was an error:", error)
}
}
.disposed(by: disposeBag)