2017-04-25 98 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