【问题标题】:Forward transformed event from Observable directly to BehaviourSubject将 Observable 直接转换为 BehaviorSubject 的事件
【发布时间】:2017-10-27 23:09:55
【问题描述】:

我对 Rx 和 RxSwift 真的很陌生,我正在尝试通过阅读和实践来学习,所以也许这个问题会让你发笑。请提前原谅我:P

我有这个架构:

MatchView -> MatchViewModel -> P2PSession -> MCSession+Rx

我对@9​​87654322@ 进行了响应式扩展,以使会话状态更改成为可观察的:

var didChangeState: Observable<(MCPeerID, MCSessionState)> {
    return RxMCSessionDelegateProxy.proxy(for: base).didChangeStateSubject.asObservable()
}

然后,我有另一个对象 P2PSession 订阅了该 observable,以便将接收到的事件转换为将其发送到 BehaviorSubject&lt;MCPeerID?&gt; 以供我的 MatchViewModel 观察,这会将其转换为发送到Variable&lt;String&gt; 将显示在标签中。

也许链接是完全荒谬的,但这是完整(但简化)的事情:

P2PSession

var connectedPeer: BehaviorSubject<MCPeerID?> = BehaviorSubject(value: nil)

mcSession.rx.didChangeState
    .subscribe(onNext: { self.connectedPeer.onNext($0.0) })
    .disposed(by: disposeBag)

MatchViewModel

var peerName = Variable("")

p2pSession.connectedPeer.asObservable()
    .map({ $0?.displayName ?? "None" })
    .subscribe(onNext: { self.peerName.value = $0 })
    .disposed(by: disposeBag)

比赛视图

viewModel.peerName.asDriver()
    .drive(peerLabel.rx.text)
    .disposed(by: disposeBag)

它的工作原理是,当一个对等点连接时,在RxMCSessionDelegateProxy 中调用一个委托方法,数据通过链传输,直到它显示在标签中。

但我认为这可以做得更优雅。是否可以将转换后的事件从可观察对象转发到主题,而无需订阅第一个可观察对象以转换并将值注入主题/变量? (正如我在P2PSession 中所做的那样)。我不知道我是否正确地解释了自己,但我认为flatMap 可以做到这一点,但我没有正确理解,也许我仍然需要subscribe,我正在尝试做一些愚蠢的事情。

非常感谢,我需要你的帮助!

【问题讨论】:

  • 你真的需要一个主题吗?因为这可以通过使用 map 链接 observables 轻松完成。主题(变量是主题)添加状态,您只是从一种类型映射到另一种类型。
  • @FelipeCypriano 也许我可以用Variable 更改我的BehaviorSubject,但我也会遇到同样的问题,对吧?你能告诉我你的解决方案的代码吗?谢谢。
  • 如果你注意到正确的答案是不依赖主题。您可能会在不需要/想要的情况下公开对类内部的读写访问权限。

标签: ios swift rx-swift reactivex


【解决方案1】:

通过Observable 公开连接的对等体,通过Driver 公开对等体名称:

let connectedPeer: Observable<MCPeerID?>
connectedPeer = mcSession.rx.didChangeState.map { $0.0 }

let peerName: Driver<String>
peerName = p2pSession.connectedPeer.map { $0.displayName ?? "None" }.asDriver(onErrorJustReturn: "None")

viewModel.peerName.drive(peerLabel.rx.text).disposed(by: disposeBag)

【讨论】:

  • 谢谢,它适用于connectedPeer,但适用于peerName 错误:Cannot convert call result type 'Observable&lt;_&gt;' to expected type 'SharedSequence&lt;DriverSharingStrategy, String&gt;!'。我找不到解决办法T_T
  • 嗯,使用peerName = p2pSession.connectedPeer.map{ $0.displayName }.asDriver(onErrorJustReturn: "None") 可以,但我不知道它是否正确。
  • 对不起,我应该添加转换。
猜你喜欢
  • 2018-02-22
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 2021-05-24
  • 1970-01-01
相关资源
最近更新 更多