ADB
ADB

Reputation: 719

How to make a dictionary containing a tuple conform to codable?

I've seen many other similar questions to mine on here already, but I've not been able to find my case - apologies if I've missed something obvious!

I've got a 'Transaction' class which contains some properties, all of which conform to codable and are saving/loading nicely. I've just added an dictionary and get the following error: Type 'Transaction' does not conform to protocol 'Decodable' and 'Encodable'.

The dictionary is:

var splitTransaction: [String:(amount: Money<GBP>, setByUser: Bool)]? {

where Money is from here: https://github.com/Flight-School/Money (Money already conforms to codable, and I have other properties of type Money that are working well.

From https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types I think I have to use Coding Keys to encode/decode splitTransaction, but does that mean I have to have a Coding Key for each of my other properties too? And then provide a way to encode/decode them too? Or is there a way to leave all the other properties encoding/decoding automatically, and just provide a way for splitTransaction to work manually.

Any guidance much appreciated!

Upvotes: 6

Views: 3257

Answers (1)

David Pasztor
David Pasztor

Reputation: 54745

The issue is that the values in your Dictionary are Tuples and tuples don't conform to Codable. Sadly you can't even extend a Tuple, since they're non-nominal types, so you'll have to either switch to another data type or implement the encoding and decoding methods yourself.

I'd suggest using a custom struct instead of the tuple, something like

struct TransactionAmount<Currency>: Codable {
    let amount: Money<Currency>
    let setByUser: Bool
}

And then in your Transaction class,

var splitTransaction: [String:TransactionAmount<GBP>]? {...

Upvotes: 9

Related Questions