Home > Mobile >  Can't seem to decode JSON
Can't seem to decode JSON

Time:10-08

I know this type of question seems to be answered a lot but I really can't seem to make this work. I'm trying to decode some JSON data into my data structs. I think the problem is there. I may have my data model wrong, but can't quite work it out. The data is not an array, there is an array within it. Its trying to decode a dictionary into array but when I try to initialise my results variable as something other than array it won't build. I'll submit my code and the JSON data in the hopes someone can shed light!

The error I'm getting is:

JSON decode failed: Swift.DecodingError.typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

thank you so much


import SwiftUI

struct DataFormatted: Codable, Hashable {
    
    var deliveryPoints: [DeliveryPoints]
    var deliveryPointCount: Int
    var postalCounty: String
    var traditionalCounty: String
    var town: String
    var postCode: String
}

struct DeliveryPoints: Codable, Hashable {
    var organisationName: String
    var departmentName: String
    var line1: String
    var line2: String
    var udprn: String
    var dps: String
    
}

struct ContentView: View {

// I reckon the error is here:
    @State private var results = [DataFormatted]()

    var body: some View {
        VStack{
            List{
                ForEach(results, id: \.self) { result in
                    Text(result.postalCounty)
                }
                
            }
        }
        .task {
            await loadData()
        }
    }
    
    func loadData() async {
        
       
        guard let url = URL(string: "https://pcls1.craftyclicks.co.uk/json/rapidaddress?key=d2be6-297a1-a60ec-0840a&postcode=aa11aa&response=data_formatted") else {
            print("Invalid URL")
            return
        }
        
        var request = URLRequest(url: url)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "GET"
        
        do {
            let (data, _) = try await URLSession.shared.data(for: request)
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            
            let decodedResponse = try decoder.decode([DataFormatted].self, from: data)
            
            results = decodedResponse
            
        } catch let jsonError as NSError {
            print("JSON decode failed: \(jsonError)")
          }
    }
}

JSON Data:

{
    "delivery_points":[
        {
            "organisation_name":"THE BAKERY",
            "department_name":"",
            "line_1":"1 HIGH STREET",
            "line_2":"CRAFTY VALLEY",
            "udprn":"12345678",
            "dps":"1A"
        },
        {
            "organisation_name":"FILMS R US",
            "department_name":"",
            "line_1":"3 HIGH STREET",
            "line_2":"CRAFTY VALLEY",
            "udprn":"12345679",
            "dps":"1B"
        }
    ],
    "delivery_point_count":2,
    "postal_county":"POSTAL COUNTY",
    "traditional_county":"TRADITIONAL COUNTY",
    "town":"BIG CITY",
    "postcode":"AA1 1AA"
}

CodePudding user response:

try something like this:

struct DataFormatted: Codable {
    var deliveryPoints: [DeliveryPoint]
    var deliveryPointCount: Int
    var postalCounty: String
    var traditionalCounty: String
    var town: String
    var postcode: String // <-- postcode
}

struct DeliveryPoint: Codable {
    var organisationName: String
    var departmentName: String
    var line1: String?
    var line2: String?
    var line3: String?
    var udprn: String
    var dps: String
}
  

and use it like this:

   let apiResponse = try decoder.decode(DataFormatted.self, from: data)

CodePudding user response:

Thank you all... @workingdog support Ukraine I used your code then added in some initial data plus changed my @main file to show ContentView(results:DataFormatted()) and it worked.

  • Related