Swift: using Alamofire and SwiftyJSON with unloaded JSON API

Using Alamofire and SwiftyJSON to retrieve some JSON is trivial:

Given JSON for example

{
    "results": [
       {
         "id": "123",
         "name": "Bob"
       },
       {
          "id": "456",
          "name": "Sally"
       }
 }

This function will work:

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

All is well and good. My problem arises when I need to load JSON from the paged API, that is, when data is collected from several calls to the API endpoint, where the JSON looks larger:

 {
    "currentPage": "1",
    "totalPages": "6"
    "results": [
       {
         "id": "123",
         "name": "Bob"
       },
       {
          "id": "456",
          "name": "Sally"
       }
     ]
 }

and then the next block will look like this:

 {
    "currentPage": "2",
    "totalPages": "6"
    "results": [
       {
         "id": "789",
         "name": "Fred"
       },
       {
          "id": "012",
          "name": "Jane"
       }
     ]
 }

In this case, I can recursively call the function to collect all the "pages", but I'm not sure how to correctly assemble all the JSON fragments:

func loadSomeJSONDataFromPagedEndPoint(page : Int = 1) {
        Alamofire.request(.GET, "http://example.com/json/" + page)
            .responseJSON { (_, _, data, _) 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()

What I would like to do is to ensure that part of the "results" of each JSON response is ultimately assembled into one array of objects (objects { "id": "123", "name": "Bob"})

: , json["totalPages"].description.toInt(), totalPages, ?

+4
1

, .

, JSON JSON. .

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 paged JSON, data , error json. , , JSON, .

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

. description SwiftyJSON, string , toInt.

Alamofire

, , JSON , , response 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] _, _, data, _ 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)
    }
}

JSON SwiftyJSON

parseJSONData SwiftyJSON, .

, . , !

+15

All Articles