Please note that I'm really new to Swift and iOS programming so some of you may find this a bit silly.
Anyway, so I am encoding an Int
object and associating it with a String
key like so:
func encodeWithCoder(aCoder: NSCoder) {
// Note that `rating` is an Int
aCoder.encodeObject(rating, forKey: PropertyKey.ratingKey)
}
Now when I try to decode it like so:
required convenience init?(coder aDecoder: NSCoder) {
let rating = aDecoder.decodeIntegerForKey(PropertyKey.ratingKey)
// Initialising a model class
self.init(rating: rating)
}
The constant rating
is expected to an Int
because decodeIntegerForKey
is expected to return an Int
by default
Build goes well, but it crashes when I run it and logs an error as replicated below.
Terminating app due to uncaught exception
'NSInvalidUnarchiveOperationException',
reason: '*** -[NSKeyedUnarchiver decodeInt64ForKey:]:
value for key (rating) is not an integer number'
But it seems to work well when I change decodeIntegerForKey
to decodeObjectForKey
and downcast the return value to an Int
.
Like so:
required convenience init?(coder aDecoder: NSCoder) {
// Replaced `decodeInteger` with `decodeObject` and downcasting the return value to Int
let rating = aDecoder.decodeObjectForKey(PropertyKey.ratingKey) as! Int
self.init(rating: rating)
}
It is getting hard for me to understand why the exception, because I encoded it as an Int
and decodeInteger
returns an Int by default.
Also, I feel like the NSInvalidUnarchiveOperationException
is telling me that I've used the wrong operation to decode the encoded object out.
This isn't making any sense to me, help
This question has been resolved. Thanks to @PhillipMills for clarifying.
The implementation was done wrong while encoding the Int
object. I was encoding it in AnyObject
instead of Int
and was trying to decode it as an Int
. And that's why I had to downcast it and decoding as an Int
wasn't working.
Encoding should have been done like so:
func encodeWithCoder(aCoder: NSCoder) {
// Note that `rating` is an Int
aCoder.encodeInteger(rating, forKey: PropertyKey.ratingKey)
}