Home > database >  SwiftUI URLSession JSONDecoder returning error when trying to parse nested Json
SwiftUI URLSession JSONDecoder returning error when trying to parse nested Json

Time:10-05

I am trying to parse a nested Json in SwiftUI for the last couple of days and I have no idea how to move forward.

At this point, I suspect that the trouble is a parameter received within the Json named "data" which might cause a confusion between the param value in struct "VTResponse" and the data param that URLSession.shared.dataTask is getting.

Here's the code at this point:

import UIKit

struct VTResponse: Decodable {
    let data: [VT]
}

struct VT: Decodable {
    var id: String
}

let token = "<TOKEN>"
let XDOMAIN = "<XDOMAIN>"

guard let url = URL(string: "https://www.lalalla.com/subdomains") else {
            fatalError("Invalid URL")
}

var request = URLRequest(url: url)
request.httpMethod = "GET"
request.setValue("x-apikey: \(token)", forHTTPHeaderField: "Authorization")

URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data, error == nil else { return }

let result = try? JSONDecoder().decode(VTResponse.self, from: data)

if let result = result {
    result.data.forEach {
        print($0.id)
    }
            }
    else {
        print("Error")
    }
}.resume()

Assuming that I define a token and domain for the query, for example, lookup all of the subdomains of "giphy.com", the Json response:

Json Response - Pastebin

As you can see in the Json response, the subdomains parameter ("id") is under a dictionary, under an array("data"). My guess is the code is trying to assign data to the variable:

guard let data = data, error == nil else { return }

But this is just a guess. And even if so, how could I solve this? Anyways, I'm getting the following output:

Error

I'm trying to get the following output:

pingback.giphy.com
media3.giphy.com
api.giphy.com
developers.giphy.com
media.giphy.com
x-qa.giphy.com
media1.giphy.com
x.giphy.com
media4.giphy.com
media0.giphy.com

Any ideas?

CodePudding user response:

try this using an x-apikey header for your token:

func fetchData(token: String, XDOMAIN: String, completion: @escaping (VTResponse) -> Void) {
    guard let url = URL(string: "https://www.virustotal.com/api/v3/domains/\(XDOMAIN)/subdomains") else {
        fatalError("Invalid URL")
    }
    
    var request = URLRequest(url: url)
    request.httpMethod = "GET"
    request.setValue("\(token)", forHTTPHeaderField: "x-apikey") // <-- here
    
    URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data else { return } // todo return some error msg
        do {
            let results = try JSONDecoder().decode(VTResponse.self, from: data)
            return completion(results)
        } catch {
            print(error) // <-- here important
        }
    }.resume()
}

And use it like this:

fetchData(token: "xxx", XDOMAIN: "www") { results in
    results.data.forEach {
        print("---> id: \($0.id)")
    }
}
  • Related