首页 > 解决方案 > RxSwift,如何更温和地使用 NotificationCenter?

问题描述

收到 IAP 购买通知,然后我从我的服务器请求交易。

下载歌曲并播放,如果交易OK。

我使用 RxSwift,以下代码有效,我想改进它。

NotificationCenter.default.rx.notification( .purchase )
        .takeUntil(self.rx.deallocated)
        .map { (noti) -> String in
                return "Not care"
              // I want to optimize this step
        }.concat(self.transactionRequest())
        .flatMap{ self.downloadSong($0) }.subscribe(onNext: { downloaded in
            if downloaded{
                self.playMusic()
            }
        })
        .disposed(by: rx.disposeBag)


  func transactionRequest()  -> Observable<String> { // ... }

  func downloadSong(_ src: String) -> Observable<Bool> { // ...  }

我不能这样使用

NotificationCenter.default.rx.notification( .purchase )
                   .takeUntil(self.rx.deallocated)
            .concat(self.transactionRequest())

因为

实例方法 'concat' 要求类型 'Notification' 和 'String' 是等价的

所以我添加了一个样板map

还有更合适的运算符或自定义运算符吗?

标签: swiftrx-swift

解决方案


正在馈送的 Observable 的返回类型concat和传递给的 Observable 的返回类型concat必须相同。我建议您改用 flatMap 。此外,您正在到处捕获self,这意味着内存问题。

这是我的做法:

NotificationCenter.default.rx.notification(.purchase)
    .flatMapLatest { [unowned self] _ in self.transactionRequest() }
    .flatMapLatest { [unowned self] in self.downloadSong($0) }
    .subscribe(onNext: { [unowned self] downloaded in
        if downloaded {
            self.playMusic()
        }
    })
    .disposed(by: rx.disposeBag)

如果您没有将所有函数都放在类中,则可以摆脱self.并且不必担心捕获 self.


推荐阅读