鉴于JSON等
{ "results": [ { "id": "123","name": "Bob" },{ "id": "456","name": "Sally" } }
这个功能会起作用:
func loadSomeJSONData() { Alamofire.request(.GET,"http://example.com/json/") .responseJSON { (_,_,data,_) in let json = JSON(data!) if let firstName = json["results"][0]["name"].string { println("first name: \(firstName)") // firstName will equal "Bob" } } }
一切都很好.当我需要从分页API加载JSON时,也就是说,当从多个调用API端点收集数据时,我的问题出现了,其中JSON看起来更像:
{ "currentPage": "1","totalPages": "6" "results": [ { "id": "123","name": "Sally" } ] }
然后下一个块看起来像:
{ "currentPage": "2","totalPages": "6" "results": [ { "id": "789","name": "Fred" },{ "id": "012","name": "Jane" } ] }
在这种情况下,我可以递归调用函数来收集所有“页面”,但我不确定如何正确地将所有JSON片段放在一起:
func loadSomeJSONDataFromPagedEndPoint(page : Int = 1) { Alamofire.request(.GET,"http://example.com/json/" + page) .responseJSON { (_,_) in let json = JSON(data!) if let totalPages = json["totalPages"].description.toInt() { if let currentPage = json["currentPage"].description.toInt() { let pageOfJSON = json["results"] // add pageOfJSON to allJSON somehow?? if currentPage < totalPages { self.loadSomeJSONDataFromPagedEndPoint(page: currentPage+1) } else { // done loading all JSON pages } } } var allJSON loadSomeJSONDataFromPagedEndPoint()
我想要发生的是将每个JSON响应的“结果”部分最终收集到一个对象数组中({“id”:“123”,“name”:“Bob”}对象)
奖金问题:我不确定为什么我需要做json [“totalPages”].description.toInt()为了获得totalPages的值,必须有更好的方法吗?
解决方法
I can’t tell from your post if you get valid JSON back for each page call or whether you need to put them altogether to complete the JSON. So let’s walk through both cases.
选项1 – 每个页面的有效JSON
你已经非常接近了,你只需稍微调整你的JSON解析并存储结果.这就是它的样子.
class PagedDownloader { var pagedResults = [AnyObject]() func loadSomeJSONDataFromPagedEndPoint(page: Int) { let request = Alamofire.request(.GET,"http://example.com/json/\(page)") request.responseJSON { [weak self] _,jsonData,_ in if let strongSelf = self { let json = JSON(jsonData!) let totalPages = json["totalPages"].stringValue.toInt()! let currentPage = json["currentPage"].stringValue.toInt()! let results = json["results"].arrayObject! strongSelf.pagedResults += results if currentPage < totalPages { strongSelf.loadSomeJSONDataFromPagedEndPoint(currentPage + 1) } else { strongSelf.parsePagedResults() } } } } func parsePagedResults() { let json = JSON(pagedResults) println(json) } }
您似乎了解SwiftyJSON的方式,因此我将让您处理parsePagedResults实现.
选项2 – 必须组装页面才能创建有效的JSON
分页JSON
首先,你不能解析部分JSON,它只是不起作用. NSJSONSerialization将失败.这意味着您不能将responseJSON序列化程序与分页JSON一起使用,因为数据始终为nil,错误始终是json序列化错误.长话短说,你需要缓存所有数据,直到它是有效的JSON,然后你可以解析.
存储分页JSON
如果你要存储它,这就是它可能看起来像一个没有Alamofire混合的简单例子.
class Pager { let page1 = "{\"currentPage\":\"1\",\"totalPages\":\"3\",\"results\":[{\"id\":\"123\",\"name\":\"Bob\"}," let page2 = "{\"id\":\"456\",\"name\":\"Sally\"},{\"id\":\"234\",\"name\":\"Christian\"}," let page3 = "{\"id\":\"567\",\"name\":\"Jerry\"},{\"id\":\"345\",\"name\":\"John\"}]}" let pages: [String] let jsonData: NSMutableData init() { self.pages = [page1,page2,page3] self.jsonData = NSMutableData() } func downloadPages() { for (index,page) in enumerate(pages) { jsonData.appendData(page.dataUsingEncoding(NSUTF8StringEncoding,allowLossyConversion: false)!) } let json = JSON(data: jsonData) println(json) if let totalPages = json["totalPages"].string?.toInt() { println("Total Pages Value: \(totalPages)") } } }
Your bonus question is answered at the end of that code chunk. You don’t want to use
description
from SwiftyJSON,but instead thestring
optional cast and then optional chain into thetoInt
method.
使用Alamofire进行分页和存储
既然您已经有了一个如何将JSON页面写入数据块的简单示例,那么让我们看看如何在Alamofire中使用相同的方法与响应序列化器一起使用.
class Downloader { var jsonData = NSMutableData() var totalPagesDownloaded = 0 let totalPagesTodownload = 6 func loadSomeJSONDataFromPagedEndPoint() { for page in 1...self.totalPagesTodownload { let request = Alamofire.request(.GET,"http://example.com/json/\(page)") request.response { [weak self] _,_ in if let strongSelf = self { strongSelf.jsonData.appendData(data as NSData) ++strongSelf.totalPagesDownloaded if strongSelf.totalPagesDownloaded == strongSelf.totalPagesTodownload { strongSelf.parseJSONData() } } } } } func parseJSONData() { let json = JSON(data: jsonData) println(json) } }
使用SwiftyJSON解析生成的JSON
在parseJSONData函数中,只需使用SwiftyJSON的所有强大功能来解析您需要的值.
I’m pretty sure that covers all your possible use cases and questions. Hope that helps!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。