PromsieKit + Alamofire for loading paged HTTP Data

ぃ、小莉子 提交于 2021-01-28 19:06:51

问题


I am migrating some code from RestKit to Alamofire. I use MagicalRecord + AlamofireObjectMapper to map the JSON into CoreData objects.

I am now faced with the following situation:

My Data lives at this URL:

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

Now I have to do this:

  • Download the first page of data from a given URL using a page-size of 50
  • If the number of loaded objects is equal to the page-size increment the start parameter by the page size
  • If the number is less than the page size combine all the loaded objects and return them to the callee.

In my previous non-Alamofire example I did use recursion for this but with PromiseKit I guess I have to do additional chaining of Promises rather than recursion of method calls.

So far I have only done simple chaining of Promises so the conditional looped chaining and how to implement this using PromiseKit is a bit of a mystery to me.


回答1:


I did come up with an approach that seems to work fine. However, I have the feeling that this could be much more concise so better answers or comments are very welcome.

I decided to combine recursion and Promises (due to a lack of better solutions). So I am passing along a currentPromise which is chained further as more pages need to be loaded.

The first method simply starts the whole process and the created Promise is instantly fulfilled with an empty array like so: Promise([Issue]()):

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

The next method does the actual work of downloading the content and parsing it.

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)
                }
        }
    }
}

The final method combines the results being passed in and the currently loaded ones. If the end of the page is reached then the results are returned using a fullfilled promise and if more pages need to be loaded then another call to the second method is issued:

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)
        }
    }
}


来源:https://stackoverflow.com/questions/38404047/promsiekit-alamofire-for-loading-paged-http-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!