2017-04-25 97 views
4

我试图找到最佳做法来处理多个子请求每个从父请求获得的值。我试图使用与此处相同的逻辑 - Reactive Cocoa 5 and ReactiveSwift network requests handling,但有一些问题。ReactiveCocoa 5,ReactiveSwift网络子请求处理和最佳做法

我们所拥有的和需要的:
1的TableView与无限滚动处理器(SVPullToRefresh)对象
2.抓取列表中的每个时间处理程序被调用
3.发送“子请求”为每个对象从响应

注:
1.所有的请求(曾经的viewController关闭(DEINIT称呼)
2.我需要有随时取消父请求的能力父+子请求)应该成为取消。这也应该取消所有的子请求。

我现在有

我知道我在“无限处理器”做的是有点“胶带”,但我是新与ReactiveSwift ...

self.tableView.addInfiniteScrollingWithActionHandler { [unowned self] in 
    self.tempMutableProperty.value = true 
} 

self.tempMutableProperty.producer.skipNil().flatMap(.latest) { [unowned self] tempValueThatIDontNeed in 
    return self.producerForParentRequest(offset: self.offset) 
     .take(during: self.reactive.lifetime) 
     .on(
      // handlers for errors, completed, etc 
      value: { [unowned self] items in 
       self.items.append(items) 
       self.tableView.reloadData() 
       self.offset += items.count 
       // SEND REQUEST #2 FOR EACH ITEM 
      } 
    ).flatMapError { error in 
     return SignalProducer.empty 
    } 
}.observe(on: UIScheduler().start() 

所以,正如你所看到的,我已经与tableView分页。我为每个页面提取对象列表。然后,对于响应中的每个项目,我需要使用请求#2获取附加信息。


流量和问题:
我当然想摆脱tempMutableProperty并以某种方式开始新parent request没有一些还挺代理
2.每个sub-request应该是独立,这意味着我想有value/error处理程序调用每个sub-request分开,并且不喜欢等待所有10个子请求,然后调用与收集所有10个反应成功处理程序。此外,某些特定的子请求失败应该不会影响其他正在运行的子请求
3.用户可以更改他的搜索请求,而不必等待整个请求处理完成。这意味着,一旦用户改变一些参数,我将清除所有项目,我需要取消所有sub-requestsparent request和所有重新开始这个。
4.除了#2,有时用户可以向下滚动以取物品的新的部分。这将意味着新的parent request应该开始,但sub-requests从以前的parent request响应应该继续工作
5。所有请求应该成为取消了self.deinit,所以这一切都应该在self.lifetime只有工作,但我不知道是什么把这个参数

我不知道,如果这一切都是可能的,而不存储一次性正确的位置/信号作为自身的特性,所以这不是一个问题,如果sub-request将作为属性以某种方式保存。


谢谢大家的帮助

回答

0

所以,我将在这里发布解决方案,为我的问题。

对于点#1我做了这一点:

let disposable = SerialDisposable() 

self.tableView.addInfiniteScrolling(actionHandler: { [unowned self] in 
    self.disposable.inner = nil // this is needed to force dispose current request before starting new one 
    self.disposable.inner = self.producer().take(during: self.reactive.lifetime) 
     .on(value: { [unowned self] value in 
      // handle as you want 
     }).start() 
}) 

帮我摆脱tempMutableProperty。取而代之的flatMapSerialDisposable使用。 所以,这个工作对我很好,而且配置请求时自动self是被破坏掉了

为我做了这等点

的想法是,我加载某些项目的表,那么我需要发送每个项目的附加请求来获取它的详细信息。所以,我创建了一个班,有3个属性 - item,itemDetail,requestSent

然后在willDisplay cell

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    if !self.items[indexPath.row].requestSent { 
     self.items[indexPath.row].details <~ self.detailedProducerForItemID(self.items[indexPath.row].item.id) 
     self.items[indexPath.row].requestSent = true 
    } 
} 

注意self.items[indexPath.row].detailsMutableProperty<Details?>

在电池本身较细节我有类似:

let (detailsSignal, detailsObserver) = Signal<MutableProperty<Details?>, NoError>.pipe(),其中Details是项目细节的类别名称。

在细胞的awakeFromNib

let details = self.detailsSignal.flatMap(.latest) { $0.producer } 

self.detailsLabel.reactive.text <~ details.map { value -> String? in 
    // handling `Details` 
} 

而在cellForRow我打电话cell.detailsObserver.send(value: self.items[indexPath.row].details)

而且,当VC的deinit叫,否则我执行新main要求,所有的请求都自动得到取消,因为当我使用self.items.removeAll()它处理所有请求。

这是粗糙的流量。如果有人对更多细节感兴趣,请不要犹豫。

0

对于第1部分,我想补充一点,变成了无限滚动的动作处理成信号的扩展:

extension Reactive where Base: UITableView { 
    public func infiniteScrollingSignal() -> Signal<Void, NoError> 
    { 
     return Signal { [unowned base = self.base] observer in 
      base.addInfiniteScrollingWithActionHandler { 
       observer.send(value:()) 
      } 

      return ActionDisposable { 
       // Unsubscribe the infinite scrolling action handler here if necessary 
      } 
     } 
     .take(during: self.lifetime) 
    } 
} 

然后你就可以连接所有的逻辑来self.tableView.reactive.infiniteScrollingSignal()

+0

嗯...这比我的解决方案稍微好一点,因为我不需要存储任何种类的一次性属性。但它只是一个“整体问题”,它仍然发送虚拟布尔值“true”,只是为了调用'flatMap'闭包。无论如何,这是一个很好的建议,这将使viewController的代码更清晰 –

+1

我认为你可以将类型从'Signal '改变为'Signal ',然后发送一个空的元组值:'observer .send(value:())'。我并不确定自己的头脑,所以我只是用布尔。 – jjoelson

+1

另外,处理你不关心的参数的Swift方法就是使用下划线,比如'flatMap(.latest){_ in ...} – jjoelson