PromsieKit + Alamofire 用于加载分页的 HTTP 数据

Posted

技术标签:

【中文标题】PromsieKit + Alamofire 用于加载分页的 HTTP 数据【英文标题】:PromsieKit + Alamofire for loading paged HTTP Data 【发布时间】:2016-07-15 19:46:50 【问题描述】:

我正在将一些代码从 RestKit 迁移到 Alamofire。我使用 MagicalRecord + AlamofireObjectMapper 将 JSON 映射到 CoreData 对象。

我现在面临以下情况:

我的数据位于此 URL:

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

现在我必须这样做:

使用页面大小50 从给定 URL 下载第一页数据 如果加载对象的数量等于页面大小,则将 start 参数增加页面大小 如果数字小于页面大小,则合并所有加载的对象并将它们返回给被调用者。

在我之前的非 Alamofire 示例中,我确实为此使用了递归,但使用 PromiseKit 我想我必须做额外的 Promises 链接,而不是方法调用的递归。

到目前为止,我只做了简单的 Promise 链接,所以条件循环链接以及如何使用 PromiseKit 实现它对我来说有点神秘。

【问题讨论】:

【参考方案1】:

我确实提出了一种似乎行之有效的方法。但是,我觉得这可能会更简洁,因此非常欢迎更好的答案或 cmets。

我决定将递归和 Promises 结合起来(由于缺乏更好的解决方案)。所以我传递了一个currentPromise,随着需要加载更多页面,它被进一步链接起来。

第一种方法简单地启动整个过程,创建的 Promise 立即用一个空数组实现,如下所示: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)
                
        
    

final 方法结合了传入的结果和当前加载的结果。如果到达页面末尾,则使用完整的承诺返回结果,如果需要加载更多页面,则再次调用第二种方法:

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)
        
    

【讨论】:

以上是关于PromsieKit + Alamofire 用于加载分页的 HTTP 数据的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire responseObject 不能用于 Bool 响应

Swift:Alamofire 能否用于将数据存储到 Google 驱动器

作为参数的数组不适用于 Alamofire

Xcode 8.3.2 不适用于 Alamofire 4.4.0

带有 Swift 3 的 Alamofire 4.3,POST 请求不适用于 URL 参数

URLSessions 或 AlamoFire 用于下载每天更新一次的网页?