Swift:将Alamofire和SwiftyJSON与分页JSON API一起使用
使用Alamofire和
SwiftyJSON检索一些JSON是微不足道的:
鉴于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的值,必须有更好的方法吗? 解决方法
你在这里有几个问题,所以让我们一次拿一个.
选项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)") } } }
使用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的所有强大功能来解析您需要的值.
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |