Search code examples
iosjsonswiftcodabledecodable

Why JsonDecoder Giving Error while trying to parse postman Url but working on other urls?


Both The Url contains Dictionary In Json Format.

import UIKit
import Foundation
struct Course  : Decodable{

    let foo1: String?
    let foo2: String?
    let fullName : String?
    let numFound : Int?
}

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

       // let jsonUrl = "https://api.plos.org/search?q=title:DNA" //Working On this Url
        let jsonUrl = "https://postman-echo.com/get?foo1=bar1&foo2=bar2"//Not Working On this Url
        guard   let url = URL(string: jsonUrl) else { return}

        URLSession.shared.dataTask(with: url) {(data,response,err) in

            guard let data = data
                else {return}

            do
            {

                 let course = try  JSONDecoder().decode([String: Course].self , from: data)
                 course.forEach { print("\($0.key): \($0.value)")}
            }
            catch let jerr
            {
                print(jerr)
            }
        }.resume()

    }
}

This Is the Error If I am Using Postman Url


Solution

  • Paste the Postman URL into a browser and look at the JSON.

    It doesn't work because there are other values than Course for other keys so decoding a [String:Course] dictionary fails.

    You have to add an umbrella struct for the root object

    struct Root : Decodable {
        let args : Course
    }
    
    struct Course : Decodable {  
        let foo1: String?
        let foo2: String?
        let fullName : String?
        let numFound : Int?
    }
    
    class ViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
    
           // let jsonUrl = "https://api.plos.org/search?q=title:DNA" //Working On this Url
            let jsonUrl = "https://postman-echo.com/get?foo1=bar1&foo2=bar2"//Not Working On this Url
            guard let url = URL(string: jsonUrl) else { return}
    
            URLSession.shared.dataTask(with: url) {(data,response,err) in
    
                guard let data = data else {return}
    
                do { 
                     let result = try  JSONDecoder().decode(Root.self , from: data)
                     print(result.args.foo1, result.args.foo2)
                } catch {
                    print(error)
                }
            }.resume()
    
        }
    }