I've having difficulty saving an NSManagedObject in userDefaults and I'd like to know a) should I be trying to do this or is this not an appropriate approach or b) if it is an appropriate approach, how can I get it to work?
I'm writing my app in Swift 2.3 and it has a few user default options, one of which is for a default "lift" (as in weightlifting, e.g. 'bench press', 'clean and jerk', 'incline bench press'). I'm actually converting them from an enum to a Core Data entity because every lift event that the user will be able to keep track of will be one of the available lifts types (for which I'll establish the appropriate relationship).
Here's the extension with the properties:
extension Lift {
@NSManaged var liftName: String
@NSManaged var type: NSSet
}
and the Lift entity with the things Xcode is complaining about:
class Lift: NSManagedObject, NSCoding {
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(liftName, forKey: "liftName")
} // Super.init isn't called on all paths before returning from initializer
required init(coder aDecoder: NSCoder) {
// Initialization of immutable variable was never used, etc...
let liftName = aDecoder.decodeObjectForKey("liftName") as! String
}
}
I've dealt with these types of errors before so my real concern is whether or not I'm headed down the wrong path.
I've read numerous threads tonight which have taught me that I'll need to encode an object (but not specifically an NSManagedObject) to save it then unencoded it when retrieving it and that my class must conform to NSCoding and what that protocol requires. But then I've seen threads that say NSManagedObjects
should NOT be stored in userDefaults
, but I don't know if that's true.
I've spent a few hours on this so before I go further, can/should this be done?
No, you should not store an NSManagedObject
in NSUserDefaults
. Core Data is an object persistence technology, so it doesn't make sense to try and persist an NSManagedObject
in some other format.
There are few alternatives you can use:
default
and again use a query to retrieve it; You would need to ensure you only set the value to true on one lift at a time.managedObject.objectId.uriRepresentation
to get a URL that you can store as a string and then use to retrieve the object later. This is probably the most complex solution and I would suggest you try one of the other options.