0

JSON decoder shows empty list however everything is coded properly. I get a json array from the server, in Xcode console it still shows an empty array.

News(news: [])

Whiel current response from a server is a valid json array:

{"news":[{"info_id":"unique id","title":"some title","description":"some description","date":"2019-07-10","time":"10:23:00"}]}

My struct to parse json is:

struct News: Codable {

let news = [Info]()

struct Info: Codable {

    let infoId: String
    let title: String
    let description: String
    let date: String
    let time: String

    private enum CodingKeys: String, CodingKey {
        case infoId = "info_id"
    }

}

}

I try to decode that array of posts with that code:

let decoder = JSONDecoder()
                let news: News = try decoder.decode(News.self, from: data)
                print("\(news)")

SOLUTION: let news = [Info]() changed to var news = [Info]()

1
  • Alright it is sorted now, I changed let news = [Info]() to var news = [Info](). Commented Jun 16, 2019 at 8:20

2 Answers 2

1

Try this .

    struct BaseNews: Codable {
    let news: [News]
}

// MARK: - News
struct News: Codable {
    let infoID, title, newsDescription, date: String
    let time: String

    enum CodingKeys: String, CodingKey {
        case infoID = "info_id"
        case title
        case newsDescription = "description"
        case date, time
    }
}


let decoder = JSONDecoder()
let news: News = try decoder.decode(BaseNews.self, from: data)

Update: based on your comment

I cannot cast news to News when decoding because it might be more objects in the array

Codables protocols need an explicit declarations of the properties inside the their body, as you can't decode let's say more than one type using the same key, or missing a key, therefore either implement the full JSON decoding keys, or navigate thru your json array slice it or do whatever you need to get the output of the needed data to decode .

Now usually when there are multiple objects types in the same array, there should be some kind of a way to tell which one is what, or at least a common keys and a nullable values between objects without missing any key .

There is also an advanced decoding practices such as overriding the initializer of the conformed party from it's decoder and manually create a container and decode every key, this will allow us to manipulate the data types, key paths , the way we like .

Side Note: it's considered bad practice for the web api to return an array that contains multiple objects types

Sign up to request clarification or add additional context in comments.

4 Comments

I cannot cast news to News when decoding because it might be more objects in the array. I still get empty array in console: [ ]
Add other keys in baseNews struct
It throws an error when I deleted initialiser in array
@D.B. i tried to explain for you, check out updated answer
0

You are already initialising the array of [Info] in the structure that is why you are getting an empty array. You just need to change

var news = [Info]()

To

var news: [Info]?

And you structures should look like this :

struct News: Codable {
    var news : [Info]
}

struct Info: Codable {

    var infoId: String?
    var title: String?
    var description: String?
    var date: String?
    var time: String?

    private enum CodingKeys: String, CodingKey {
        case infoId = "info_id"
    }

}

and you are good to go.

1 Comment

it says "Expected member name or constructor call after type name", that's why I did it. Then another warning 'Type 'Parties' does not conform to protocol 'Decodable' and Encodable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.