1

I am going round in circles trying to work with a Codable Struct. I can nearly get it to work, but I get an error at the end.

Here is a simple example:

struct Stuff: Codable {
    var title: String = ""
    var code: Int = 0
    struct Item {
        var name: String
        var value: Int
    }
    var items: [Item] = []
    init(from decoder: Decoder) throws { }
    func encode(to encoder: Encoder) throws { }
}

var items: [Stuff.Item] = []

items.append(Stuff.Item(name: "Apple", value: 1))
items.append(Stuff.Item(name: "banana", value: 2))

var stuff = Stuff(title: "test", code: 23, items: items)

On that last line I get the error

Extra arguments at positions #1, #2, #3 in

Clearly the nested struct is OK. If I remove the :Codable and the init() and func encode() it works as I would have expected.

What is the correct way to do this?

1 Answer 1

6

Reason:

Since you've implemented init(from:) initialiser, so the default init is not available.

That the reason, it is not able to find init(title:,code:,items:)

Solution:

Implement the initialiser init(title:,code:,items:) manually. Also, conform Item to Codable as well.

Now, the struct Stuff must look like,

struct Stuff: Codable {
    var title: String = ""
    var code: Int = 0
    struct Item: Codable {
        var name: String
        var value: Int
    }
    
    var items: [Item] = []
    init(from decoder: Decoder) throws { }
    func encode(to encoder: Encoder) throws { }
    
    init(title: String, code: Int, items: [Item]) {
        self.title = title
        self.code = code
        self.items = items
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

It's also worth noting that if one does need to implement init(from:), it's better to do in as extension Stuff: Codable {}, which would keep the memberwise initializer for the type
Thanks for your answer. The problem is that I will need to customise the decoder and the encoder.
@Manngo If that is the case, then you need to implement init(title:,code:,items:) manually. Updated the answer.

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.