【问题标题】:RxSwift best practice: Shall I use a Subject for my internal data source?RxSwift 最佳实践:我应该为我的内部数据源使用主题吗?
【发布时间】:2017-11-07 08:19:16
【问题描述】:

我对 Rx 世界还很陌生,我想知道我是否做得对,或者我是否有误解并违反了最佳实践。如果是这样,如果您能指出正确的方向,我会很高兴。

在我的 iOS 应用程序中,我需要调用 Web 服务来检索我的数据。基本上我可以打两个电话:

  • 对收集资源 (/devices) 的调用
  • 调用单个资源 (/devices/{id})

为了减少我需要做的调用量,我认为将数据本地存储在内存中是个好主意,这样当我从列表视图(显示所有设备)转到详细视图(显示单个设备),我不必调用单个资源。

相反,我只会在用户使用 pull 在详细信息屏幕内刷新然后将数据写回用作列表屏幕数据源的集合时进行此调用。

现在由于应用程序在移动设备上运行,在调用网络服务时可能会出现多个错误,如果发生错误,我想向用户显示一条消息以告知问题。

我正在考虑使用 Singleton 类中的 Subject 作为我的 UI 订阅的数据源。每当我需要刷新列表时,我都会使用我的 Web 服务调用创建一个新的 observable,它的副作用是向 Subject 填充新数据,但不会向 Subject 填充 onError 或 onComplete 事件。

我希望这段伪代码能更好地解释我的意思:

//Pull-to-refresh function
Observable.create { observable in
  let hud = HUD("loading devices")
  self.hud = hud
  observable.next()
  return Disposable.create { hud.dismiss() }
}
.flatMap {
  return DeviceService.getList() //The web service
}
.flatMap { devices in
  DeviceSingleton.devicesSubject.next(devices) //The singleton
  return Observable.just()
}
.subscribe(
  onNext: { self.hud.dismiss() }
  onError: { error in 
      self.hud.dismiss()
      self.displayError(error)
  }
)
.disposed(by: disposeBag)

详细信息屏幕中的下拉刷新看起来很相似,但它涉及从主题获取当前数据,然后更换更新的设备并重新发布数据,如下所示:

//Pull-to-refresh function in detail screen
let id = ...
Observable.create { observable in
  let hud = HUD("loading devices")
  self.hud = hud
  observable.next()
  return Disposable.create { hud.dismiss() }
}
.flatMap {
  return DeviceService.getDevice(id: id) //The web service
}
.flatMap { device in
  let devices = try! DeviceSingleton.devicesSubject.value()
  let updatedDevices = self.updateDevice(device, in: devices) //removing old device, adding new one, sorting, etc.
  DeviceSingleton.devicesSubject.next(devices) 
  return Observable.just()
}
.subscribe(
  onNext: { self.hud.dismiss() }
  onError: { error in 
      self.hud.dismiss()
      self.displayError(error)
  }
)
.disposed(by: disposeBag)

这是正确的吗?这是有效的吗?有什么更好的方法?我认为一个问题可能是重新加载单个设备不仅会在用户拉动刷新时发生,而且还会在远程通知进来时发生。

我希望你能告诉我我是否正确使用了 Rx,或者我在这里做错了什么。

【问题讨论】:

    标签: ios swift reactive-programming rx-swift


    【解决方案1】:

    看看 .materialize().switchLatest() 运算符,它们在这种情况下会派上用场。

    我个人更喜欢使用这个小型库来保持最新状态 - https://github.com/maxvol/RaspSwift

    【讨论】:

      猜你喜欢
      • 2015-09-25
      • 2019-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-12
      • 1970-01-01
      • 2011-05-26
      • 1970-01-01
      相关资源
      最近更新 更多