1
votes

I try to parse a json that my backend team make. But json kinda weird and I can't ask the backend team to change the json. so Here are the json:

{
"nama": [
    "Tigor Franky",
    "Achmad Fauzi",
    "Mario David Lela Muda",
    "Mily Anggreini Hutasuhut",
    "Arif Fahmi ST",
    "Satwika Narindra Dhipa",
    "Mujib Burahman",
    "Aresty Puji Harjanty",
    "Rio Jatmiko",
    "Halasson Sitanggang"
],
"u_id": [
    196,
    113,
    114,
    149,
    115,
    116,
    117,
    118,
    119,
    120
],
"totalakhir": [
    14.15,
    1.74,
    1.25,
    0.75,
    0,
    0,
    0,
    0,
    0,
    0
   ]
 }

so, this is new to me. How can I decode this?

so far I try this but theres an error that say

"typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "nama", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "Expected to decode Dictionary but found a string/data instead.", underlyingError: nil))"

I try to make a struct like this:

struct HOF : Codable {
let nama : [Nama]
let u_id : [U_Id]
let totalakhir : [TotalAkhir]
}

struct Nama : Codable {
let namaa : String

enum CodingKeys : String, CodingKey {
    case namaa = "nama"
   }
}

struct U_Id : Codable {
let u_idd : Int

enum CodingKeys : String, CodingKey {
    case u_idd = "u_id"
   }
}

I know I'm wrong at making the struct but I just don't know how to make the struct.

2
The “nested structs” are wrong. Replace let nama : [Nama] by let nama : [String], and similarly for the other properties of struct HOF. - Martin R
Tell your backend team that it is more efficient to send dictionaries rather than multiple arrays even though the amount of sent data is a bit higher. - vadian
copy this json response to app.quicktype.io and it will automatically create the struct. try it once - iOSArchitect.com

2 Answers

2
votes

Change struct HOF to this and remove the other data types,

struct HOF : Codable {
    let nama : [String]
    let u_id : [Int]
    let totalakhir : [Decimal]
}

It seems lists are related to the same user so i would suggest asking your backend to change the json structure as below,

{
"hof": [
    {
      "nama": "Tigor Franky",
      "u_id": 196,
      "totalakhir": 14.15
    },
    {
      "nama": "Mily Anggreini Hutasuhut",
      "u_id": 113,
      "totalakhir": 1.74
    }
 ]
}

So, your data type will change to this,

struct HofUser : Codable {
    let nama : String
    let u_id : Int
    let totalakhir : Decimal
}

struct Response : Codable {
    let hof : [HofUser]
}

This will allow you to have only one list where each element has all the information related to a particular user.

0
votes

Since String Int & Double are Codable types. Thus an array of Codable types will work with Codable.

So there is no need to make types for U_Id or Nama

You can make your model as shown in the code below. Codable will do the rest of the work for you. You can run this sample in a playground and see the decoded output.

import Foundation

let json = """
{
"nama": [
    "Tigor Franky",
    "Achmad Fauzi",
    "Mario David Lela Muda",
    "Mily Anggreini Hutasuhut",
    "Arif Fahmi ST",
    "Satwika Narindra Dhipa",
    "Mujib Burahman",
    "Aresty Puji Harjanty",
    "Rio Jatmiko",
    "Halasson Sitanggang"
],
"u_id": [
    196,
    113,
    114,
    149,
    115,
    116,
    117,
    118,
    119,
    120
],
"totalakhir": [
    14.15,
    1.74,
    1.25,
    0.75,
    0,
    0,
    0,
    0,
    0,
    0
   ]
 }
""".data(using: .utf8)!

struct DataModel: Codable {
    let nama: [String]
    let uId: [Int]
    let totalakhir: [Double]
    private enum CodingKeys: String, CodingKey {
        case nama
        case uId = "u_id"
        case totalakhir
    }
}

let em1 = try JSONDecoder().decode(DataModel.self, from:json)

print(em1)