Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 280
ADB Avatar asked May 20 '19 11:05

ADB


People also ask

Are Dictionaries Codable Swift?

A lot of Swift's built-in types already conform to Codable by default. For example, Int , String , and Bool are Codable out of the box. Even dictionaries and arrays are Codable by default as long as the objects that you store in them conform to Codable .

How do you use any in Codable Swift?

In summary: you shouldn't use 'Any', but have 2 optional properties (one of type 'String' and one 'Int' in your case) and try decoding the JSON value as both. Moreover, your case is actually quite simple, since 'Int' can always be converted to 'String'.

What is Codable and Decodable?

Decodable protocol Decodable : A type that can decode itself from an external representation (bytes to object) Encodable protocol Encodable : A type that can encode itself to an external representation. ( object to bytes) Codable = both encoding and decoding.

Where is the Codable protocol adopted for what purpose?

So, what is Codable? Codable, introduced in Swift 4, provides a standardized approach to encode and decode custom types. It can be adopted by custom types by conforming to Codable protocol.


1 Answers

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>]? {...
like image 112
Dávid Pásztor Avatar answered Oct 16 '22 21:10

Dávid Pásztor