【问题标题】:Creating Observable which wraps observable创建包装可观察对象的可观察对象
【发布时间】:2017-04-21 20:01:37
【问题描述】:

我有一个返回 observable 的方法。

在这个方法中我订阅了rxbluetooth observable。除了永远不会调用 onComplete 之外,它运行良好。

这是我的代码:

private func getWifiConfig() -> Observable<String?> {

  return Observable.create { [ weak self ] observer in

    if let strongSelf = self {

      tileConnect.peripheral.connect()
        .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
        .flatMap { $0.discoverServices([ strongSelf.serviceUUID ]) }
        .flatMap { Observable.from($0) }
        .flatMap { $0.discoverCharacteristics([ strongSelf.wifiCharacteristicUUID ])}
        .flatMap { Observable.from($0) }
        .flatMap { $0.readValue() }
        .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
        .subscribe(onNext: {
          if let data = $0.value {
            if let configDelimitedString = String(data: data, encoding: .utf8) {
              observer.onNext(configDelimitedString)
            }
          }
        }, onError: { error in
          LOG_SENSOR_MANAGER("getWifiConfigFromCharacteristic. onError: \(error.localizedDescription)")
          observer.onError(error)
        }, onCompleted: {
          LOG_SENSOR_MANAGER("getWifiConfigFromCharacteristic. onCompleted")
                        observer.onCompleted() // <---- NEVER CALLED
        }, onDisposed: {
          LOG_SENSOR_MANAGER("getWifiConfigFromCharacteristic. onDisposed")  // <---- NEVER CALLED
        })
        .disposed(by: strongSelf.disposeBag)
      }

      return Disposables.create()
    }
  }

你知道为什么吗?

【问题讨论】:

  • 两个思路:第一个在onCompleted()之前被处理第二个每次出错,重试。
  • retrysubscribe 之间添加debug() 并发布输出。
  • @DanielT,是的,我正在使用 RxBluetoothKit
  • 似乎在处理一次性用品之前不会调用 Competed 和 Disposed 。使用计时器定期调用 getWifiConfig。也许我做错了什么......

标签: swift rx-swift rxiosble


【解决方案1】:

你可以试试这个:

private func getWifiConfig() -> Observable<String?> {

    return Observable.create { [ weak self ] observer in

        if let strongSelf = self {

            tileConnect.peripheral.connect()
                .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
                .flatMap { $0.discoverServices([ strongSelf.serviceUUID ]) }
                .flatMap { Observable.from($0) }
                .flatMap { $0.discoverCharacteristics([ strongSelf.wifiCharacteristicUUID ])}
                .flatMap { Observable.from($0) }
                .flatMap { $0.readValue() }
                .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
                .subscribe(onNext: {
                    if let data = $0.value {
                        if let configDelimitedString = String(data: data, encoding: .utf8) {
                            observer.onNext(configDelimitedString)
                            observer.onCompleted() // <- Call it here
                        }
                    }
                }, onError: { error in
                    LOG_SENSOR_MANAGER("getWifiConfigFromCharacteristic. onError: \(error.localizedDescription)")
                    observer.onError(error)
                })
               .disposed(by: strongSelf.disposeBag)
        }

        return Disposables.create()
    }
}

编辑:改善外观。你可以使用guard 来强引用自我:

private func getWifiConfig() -> Observable<String?> {

    return Observable.create { [ weak self ] observer in

        guard let `self` = self else { return } // strong reference to self. Now you can use self as strongSelf

        // subscription
        let subscription = tileConnect.peripheral.connect()
            .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
            .flatMap { $0.discoverServices([ self.serviceUUID ]) }
            .flatMap { Observable.from($0) }
            .flatMap { $0.discoverCharacteristics([ self.wifiCharacteristicUUID ])}
            .flatMap { Observable.from($0) }
            .flatMap { $0.readValue() }
            .retry(.delayed(maxCount: 30, time: 1), scheduler: MainScheduler.instance)
            .subscribe(onNext: {
                if let data = $0.value, 
                let configDelimitedString = String(data: data, encoding: .utf8) {

                    observer.onNext(configDelimitedString)
                    observer.onCompleted() // <- Call it here
                }
            }, onError: { error in
                LOG_SENSOR_MANAGER("getWifiConfigFromCharacteristic. onError: \(error.localizedDescription)")
                observer.onError(error)
            })


        // Dispose the subscription
        return Disposables.create {
            subscription.dispose()
        }
    }
}

【讨论】:

  • 这不起作用。守卫让self... 没有被处决。你能解释一下发生了什么吗?
  • 使用guard let self = self else { return },您可以访问self 而不是self?strongSelf。您使用保留字“self”创建对 self 的强引用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-12
  • 2016-10-06
  • 2019-09-09
  • 1970-01-01
  • 2019-01-30
相关资源
最近更新 更多