2016-07-15 7 views
0

RestKitからAlamofireにいくつかのコードを移行しています。私は、MagicalRecord + AlamofireObjectMapperを使用して、JSONをCoreDataオブジェクトにマップします。PromsieKit +ページングされたHTTPデータをロードするためのAlamofire

私は今、次のような状況に直面しています:

マイデータは、次のURLで住ん:

http://domain.com/api/resources?start=XX&limit=YY 

は今、私はこれをしなければならない。

  • データの最初のページをダウンロードページサイズが50であるURLから
  • ロードされたオブジェクトの数がページサイズの増分と等しい場合startページサイズによるパラメータ
  • 数値がページサイズより小さい場合は、ロードされたすべてのオブジェクトを結合し、それらを呼び出し先に返します。

以前のAlamofire以外の例では、私はこれに対して再帰を使用しましたが、PromiseKitでは、メソッド呼び出しの再帰ではなく、Promisesの連鎖を追加する必要があると思います。

これまでのところ私はPromisesを単純に連鎖させただけなので、条件付きループチェインとPromiseKitを使ってこれを実装する方法は私にとって謎のビットです。

答えて

1

私はうまくいくと思われるアプローチを考え出しました。しかし、私はこれがはるかに簡潔であると感じているので、より良い回答やコメントが大歓迎です。

私は再帰と約束を組み合わせることを決めました(より良い解決策がないため)。だから私はcurrentPromiseに沿って渡しています。これはさらに多くのページを読み込む必要があるため、さらにチェーンされています。

第一の方法は、単純に全体のプロセスを開始し、作成された約束を瞬時ようなので、空の配列で満たされる:Promise([Issue]())

func loadAllPagedIssues(repository: Repository) -> Promise<[Issue]>{ 
    return loadPagedIssues(repository, limit: Config.apiPageSize, start: 0, currentPromise: Promise([Issue]())) 
}  

次の方法は、コンテンツをダウンロードし、それを解析する実際の作業を行います。

func loadIssues(url: String, repository: Repository) -> Promise<[Issue]>{ 
    return Promise{ fullfill, reject in 

     self.manager 
      .request(.GET, url, headers: self.headers) 
      .responseArray(keyPath: "issues", context: repository) { (response: Response<[Issue], NSError>) in 
       switch response.result{ 
       case .Success(let value): 
        fullfill(value) 
       case .Failure(let e): 
        reject(e) 
       } 
     } 
    } 
} 

最後のメソッドは、渡された結果と現在ロードされている結果を結合します。ページの終わりに達すると、フルフィルメント済みの約束を使用して結果が返され、さらにページをロードする必要がある場合は、別のメソッド呼び出しが発行されます。

func loadPagedIssues(repository: Repository, limit: Int, start: Int, currentPromise: Promise<[Issue]>) -> Promise<[Issue]>{ 

    let url = baseURL + Config.pagedIssuesPath.replaceTokens(
     [ 
      "repo": repository.slug, 
      "limit": String(limit), 
      "start": String(start) 
     ] 
    ) 

    let loadPromise = self.loadIssues(url, repository: repository) 
    return when(loadPromise, currentPromise).then{ newIssues, existingIssues -> Promise<[Issue]> in 

     let combined = Promise<[Issue]>(newIssues + existingIssues) 
     if newIssues.count < limit{ 
      // Reached the end of the page 
      return combined 
     } else { 
      return self.loadPagedIssues(repository, limit: limit, start: (start + limit), currentPromise: combined) 
     } 
    } 
} 
関連する問題