加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift:将Alamofire和SwiftyJSON与分页JSON API一起使用

发布时间:2020-12-14 04:51:41 所属栏目:百科 来源:网络整理
导读:使用Alamofire和 SwiftyJSON检索一些JSON是微不足道的: 鉴于JSON等 { "results": [ { "id": "123","name": "Bob" },{ "id": "456","name": "Sally" } } 这个功能会起作用: func loadSomeJSONData() { Alamofire.request(.GET,"http://example.com/json/")
使用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的值,必须有更好的方法吗?

解决方法

你在这里有几个问题,所以让我们一次拿一个.

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 the string optional cast and then optional chain into the toInt 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!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读