infernouk infernouk - 7 days ago 6
JSON Question

Swift: Parsing JSON with Multiple pages?

I want to parse multiple JSON files, each JSON file has a link to a consecutive page until the next page result is null. I have been able to retrieve the first page, but am unsure how to handle the consecutive URL's successfully?

Here is my data fetch

open class ApiService: NSObject {

let requestUrl = "https://wger.de/api/v2/exercise/?format=json&language=2&status=2"

open func getData(completionHandler: @escaping (NSDictionary?, NSError?) -> Void) -> Self {

Alamofire.request(requestUrl, method: .get, encoding: URLEncoding.default)
.responseJSON { response in

switch response.result {

case .success(let data):
print("Request was sucessful")
completionHandler(data as? NSDictionary, nil)

case .failure(let error):
print("Request failed with error: \(error)")
completionHandler(nil, error as NSError?)
}
}
return self
}
}


and then this is my VC call

func getApiData() {

let _ = apiService.getData() {
(data, error) in
if let data = data {
if let results = data["results"] as? [[String:Any]] {
for result in results {
if let exercise = Exercise(dictionary: result) {
self.exercises.append(exercise)
}
}
self.exercisesTableView.reloadData()
}
}
}
}


This is the JSON link


https://wger.de/api/v2/exercise/?format=json&language=2&status=2

Answer

Using URL Request & URL Session - iOS SDK Classes. I haven't used Almofire extensively...but this should help you out.

import UIKit
import Foundation

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let initialURLString = "https://wger.de/api/v2/exercise/?format=json&language=2&status=2"
        getDataFromAPI(URLString:initialURLString)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func getDataFromAPI(URLString: String) {

        let APIURL: URL = URL(string: URLString)!

        var request = URLRequest(url: APIURL)
        request.httpMethod = "GET"

        let sessionConfig = URLSessionConfiguration.default
        let session = URLSession(configuration: sessionConfig)
        let task = session.dataTask(with: request) {data, response, err in
            print("Entered the completionHandler")
            if let json = try? JSONSerialization.jsonObject(with: data!) as! [String:Any]
            {
                if let nextURL = json["next"] as? String
                {
                    print("NEXT URL: \(nextURL)")
                    self.getDataFromAPI(URLString: nextURL)
                }
                else
                {
                    print("No Next URL")
                    //NO NEXT URL FOUND
                    //REFRESH UI TABLE DATA SOURCE
                }
            }
        }
        task.resume()
    }
}

Updating your Code (I have not compiled it )

open class ApiService: NSObject {

open func getData(requestUrl: String, completionHandler: @escaping (NSDictionary?, NSError?) -> Void) -> Self {

    Alamofire.request(requestUrl, method: .get, encoding: URLEncoding.default)
        .responseJSON { response in

            switch response.result {

            case .success(let data):
                print("Request was sucessful")
                completionHandler(data as? NSDictionary, nil)

            case .failure(let error):
                print("Request failed with error: \(error)")
                completionHandler(nil, error as NSError?)
            }
    }
    return self
}
}

Your Code in View Controller

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        let initialURLString = "https://wger.de/api/v2/exercise/?format=json&language=2&status=2"
        getApiData(dataURL:initialURLString)
    }

func getApiData(dataURL: String) {

let _ = apiService.getData(requestUrl: dataURL) {
    (data, error) in
    if let data = data {
        if let results = data["results"] as? [[String:Any]] {
            for result in results {
                if let exercise = Exercise(dictionary: result) {
                    self.exercises.append(exercise)
                }
            }
            self.exercisesTableView.reloadData()
        }
        if let nextURL = json["next"] as? String
        {
            print("NEXT URL: \(nextURL)")
            self.getApiData(dataURL:nextURL)
        }
    }
}
}
Comments