danthorpe / Money

Swift value types for working with money & currency
MIT License
933 stars 91 forks source link

Class does not conform to NSCoding Protocol #77

Closed jaramirez1729 closed 6 years ago

jaramirez1729 commented 7 years ago

I recently converted a few of my Doubles to type Money, but I realized that the types that are of type Money are not able to be saved into NSCoder because the class does not conform to the NSCoding protocol, therefore values of type Money cannot be saved on disk. The app crashes as soon as it tries to save a value of type Money: unrecognized instance sent to selector.

danthorpe commented 7 years ago

Hi @jozemite well, yes, these are value types. Like Double which also does not conform to NSCoding as they're not NSObject subclasses.

As with a Double, to encode it to disk, you would wrap it in an archivable class. You can do this with Money too, using a framework called ValueCoding. This was initially written in the days of Swift 1, and Apple have now added their own ReferenceConvertible protocol in Swift 3, which could offer another avenue of investigation.

So, how to encode & decode Money types using ValueCoding? You can see how this is done in the tests but essentially:

Encoding

let pounds: GBP = 10
let data = NSKeyedArchiver.archivedData(withRootObject: pounds.encoded)

Decoding

let unarchived = NSKeyedUnarchiver.unarchiveObject(with: data) as Any?
if let pounds = GBP.decode(unarchived) {
    print("We have \(String(describing: pounds))")
}