init(from decoder: Decoder) not running when decoding an array of classes

Let's say we have 2 decodable structs in Swift 5.5, and one of them has a property that contains an array of one of the structs:

struct MySecondDecodable: Decodable {
    public let mySecondProperty: String

    private enum CodingKeys: String, CodingKey {
        case mySecondProperty
    }

    init(from decoder: Decoder) {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        mySecondProperty = try values.decode(String.self, forKey: .mySecondProperty)
    }
}

struct MyDecodable: Decodable {
    public let myProperty: [MySecondDecodable]

    private enum CodingKeys: String, CodingKey {
        case myProperty
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        myProperty = try values.decode([MySecondDecodable].self, forKey: .myProperty)
    }
}

I cannot breakpoint on MySecondDecodable's init function. In fact, I cannot even see it's running. Why is this happening? Why can't I breakpoint the initialization of every single MySecondDecodable in the array? Is there a way to do such a thing?

Answered by OmerFlame in 705648022

In the end, I couldn't fix it but I found the issue in my decoder and fixed it. The example I gave didn't really reflect my situation. My situation involved many different structs from many different places in my code. Putting them in here would be... unproductive and very confusing, to say the least.

Thanks for your attention though!

If you put a print statement in the init, what do you get ? Could you show code where you instantiate the struct ?

I do not see it being output to the console.

Can you post an example where things actually fail? Because I put your code into a small test project (see below) and it works fine for me. Specifically, it prints:

MyDecodable(myProperty: [xxst.MySecondDecodable(mySecondProperty: "Hello"), xxst.MySecondDecodable(mySecondProperty: "Cruel"), xxst.MySecondDecodable(mySecondProperty: "World!")])

This is with Xcode 13.2.1 on macOS 12.2.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"


import Foundation

struct MySecondDecodable: Decodable {
    public let mySecondProperty: String

    private enum CodingKeys: String, CodingKey {
        case mySecondProperty
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        mySecondProperty = try values.decode(String.self, forKey: .mySecondProperty)
    }
}

struct MyDecodable: Decodable {
    public let myProperty: [MySecondDecodable]

    private enum CodingKeys: String, CodingKey {
        case myProperty
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        myProperty = try values.decode([MySecondDecodable].self, forKey: .myProperty)
    }
}

func main() throws {
    let json = """
        {
            "myProperty": [
                {
                    "mySecondProperty": "Hello"
                },
                {
                    "mySecondProperty": "Cruel"
                },
                {
                    "mySecondProperty": "World!"
                }
            ]
        }
        """
    let d = try JSONDecoder().decode(MyDecodable.self, from: Data(json.utf8))
    print(d)
}

try! main()
Accepted Answer

In the end, I couldn't fix it but I found the issue in my decoder and fixed it. The example I gave didn't really reflect my situation. My situation involved many different structs from many different places in my code. Putting them in here would be... unproductive and very confusing, to say the least.

Thanks for your attention though!

init(from decoder: Decoder) not running when decoding an array of classes
 
 
Q