我有一个案例,我正在使用第三方库,我想把它变成一个Observable . 适当地,库是围绕代表设计的,正如人们所期望的那样,我正在包装它 . 该库执行异步操作,并在完成后使用结果调用它的委托 .
我绝对想利用observable的 cold
性质,只有在有人订阅时才开始操作 . 我有一个有效的解决方案,我只是非常有缺陷,我错过了对 RxSwift
的一些重要理解,或者可能有一种更简单的方法来实现相同的目标 .
public final class RxLibBridge: LibDelegate{
let lib = Lib()
let _source = PublishSubject<[LibResult]>()
public init(){
lib.delegate = self
}
public func asObservable() -> Observable<[LibResult]>{
// create a cold observable to start
// the Lib's async operation on subscribe.
return Observable<Void>.create{
observer in
self.lib.startOperation()
// emit and complete
observer.onNext(())
observer.onCompleted()
return Disposables.create()
}
// convert the `Void` observable into an observable from the
// PublishSubject
.flatMapLatest{self._source}
}
// the lib's completion delegate method
public func lib(_ lib: Lib, didFinishWithResult results: [LibResult]) {
// grab the PublishSubject, emit the result and complete
let observer = _source.asObserver()
observer.onNext(results)
observer.onCompleted()
}
}
所以我的问题是:这是Rx中的合适模式吗?它再次起作用:
RxLibBridge()
.asObservable()
.subscribe(...)
仅仅因为它起作用并不意味着我没有从根本上误解了处理这种情况的正确方法 .
我知道RxSwift中有一种方法可以处理这样的事情:
https://samritchie.net/2016/05/12/rxswift-delegateproxy-with-required-methods/
我试过这种方法,但看起来自2015年以来API发生了变化 . 也就是说,在扩展中添加 rx_delegate
方法时,在上面的链接中找不到 proxyForObject
.
此外,这种方法似乎有利于纯 Objective-C
[UIKit / AppKit] API . 在我尝试关注链接的示例时,我正在编辑第三方lib的源代码,以使委托方法 optional
并将其公开给 @objc
. lib的委托是 required
,我宁愿不用fork来进行修改 .
这个SO答案为上面的2个链接提供了更新的API:
Can not use proxyForObject function in DelegateProxyType (rxSwift)
1 回答
因此,在挖掘了一些之后,看起来这将使用所需的委托方法,为
RxSwift 3.3.1
更新 . 这是使用他们的DelegateProxy
系统 .那是大约28 LOC . 我原来的“包装”(见下面的更新版本),但我不知道它是最好的是21 LOC;另外6个半打?
在我的特殊情况下,我只需要担心1个委托方法 . 如果您正在使用具有多个委托的某些功能,我认为
DelegateProxy
extension
方法将更加实用,并且在这种情况下是更好的选择 .关于我使用
Void
observable的原始试用包装物,看起来用flatMapLatest
改变流是完全可以接受的,如下所示:在按下按钮时发送连续事件:https://stackoverflow.com/a/39123102/1060314
请注意,从
flatMapLatest
返回一个新的Observable
. 作者引用了RxSwift slack channel
,所以我认为这至少是可以接受的 .这是我的包装版本的更新版本,我认为可能会更清洁: