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!
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 .
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'.
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.
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.
The issue is that the values in your Dictionary
are Tuple
s 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>]? {...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With