To avoid being an XY problem, here's some background:
My app allows users to create and save a lot of settings kinda like the Xcode's fonts and colors chooser:

This is because there are a lot of things that users can set. It would be easier to just tap on a saved setting instead of setting all those things again.
I used Core Data to store the settings the user saved. Each setting the user created is an instance of an NSManagedObject subclass. And now I need to store the selected setting persistently so that the user will have the same setting selected as before when the app reopens.
My first thought was to store the NSManagedObject subclass instance in NSUserDefaults. But according to the docs, I can't store it unless I convert it to NSData:
A default object must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary.
Then I tried storing the objectID of the NSManagedObject subclass instance. I see that there is a URIRepresentation() method that returns an NSURL. So I thought this would work:
NSData(contentsOfURL: selectedOption!.objectID.URIRepresentation())
But the initializer failed somehow.
Now I realize that this is a stupid idea because even if I can convert it to NSData, I can't convert NSData back to NSManagedObjectID!
According to this question, the OP seems to be able to store the object id:
I store the selected theme objectID in NSUserDefaults so that when the app restarts, the selected theme will still be intact.
How can I do that?
NSUserDefaults has "convenience methods"
public func setURL(url: NSURL?, forKey defaultName: String)
public func URLForKey(defaultName: String) -> NSURL?
which allow to store and retrieve a NSURL like the one obtained
by URIRepresentation(). The conversion to and from NSData
is handled transparently. From the documentation:
When an NSURL is stored using
-[NSUserDefaults setURL:forKey:], some adjustments are made:
- Any non-file URL is written by calling
+[NSKeyedArchiver archivedDataWithRootObject:]using the NSURL instance as the root object.- ...
When an NSURL is read using
-[NSUserDefaults URLForKey:], the following logic is used:
- If the value for the key is an NSData, the NSData is used as the argument to
+[NSKeyedUnarchiver unarchiveObjectWithData:]. If the NSData can be unarchived as an NSURL, the NSURL is returned otherwise nil is returned.- ...
So saving the managed object ID is simply done as
NSUserDefaults.standardUserDefaults().setURL(object.objectID.URIRepresentation(),
forKey: "selected")
and retrieving the object ID and the object for example like this:
if let url = NSUserDefaults.standardUserDefaults().URLForKey("selected"),
let oid = context.persistentStoreCoordinator!.managedObjectIDForURIRepresentation(url),
let object = try? context.existingObjectWithID(oid) {
print(object)
// ...
}
For alternative approaches of saving the selected settings, see the above comment.
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