How to store custom object in User Defaults - IOS - ios

I created one custom class & created object for that class. I want to store that object into NSUserDefault. I am getting error while set the object into userfaults. How can I set?

You have to implement the NSCoding protocol in your class & implement the protocols methods.
This is simply serialization. While storing the object you should serialize(NSKeyedArchiver) the class & same as retrieval you should unserialize(NSKeyedUnArchiver) that object.
the methods are
(void)encodeWithCoder:(NSCoder *)aCoder;
(id)initWithCoder:(NSCoder *)aDecoder;

As the documentation states:
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. If you want to store any
other type of object, you should typically archive it to create an
instance of NSData.
The simplest way of creating an instance of NSData is by using an NSKeyedArchiver.

The most probably reason is that you have something hard to archive in your structure.
Here is a quote from the NSUserDefaults Class Reference that you might find useful:
The NSUserDefaults class provides convenience methods for accessing common types such as floats, doubles, integers, Booleans, and URLs. 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. If you want to store any other type of object, you should typically archive it to create an instance of NSData. For more details, see Preferences and Settings Programming Guide.
Edit.
Beaten to the punch by Stephen, give the man a prize :)

Related

How can I save a Swift dictionary structure?

I have a Swift dictionary structure ([String : CustomObject]) that I need to save once and then reload later whenever the application launches. How do I go about saving and reloading a dictionary using Swift?
you can convert the Dictionary to NSData link here and then save it to NSUserDefaults as it is here
If you have custom objects then you need to make them conform to the NSCoding protocol. This means implementing the methods encodeWithCoder and initWithCoder. It comes down to deconstructing the state values of your object to data types that are either "property list" types, or types that also conform to NSCoding. Your implementation of encodeWithCoder can, encode it's properties that are objects that conform to NSCoding by calling encodeObject:forKey:

What is the difference between NSObject and AnyObject? When to use the two?

I'm trying to create an array to store Strings or an array of custom class. Am I better off creating a dictionary?
AnyObject is Swift's representation of Objective-C's id type. It's more general than NSObject (i.e. every NSObject is an AnyObject, but not every AnyObject is a NSObject).
On the other part of the question - depends on how you intend to use the structure. Using a more particular class for the generic structure (Swift's typed array or dictionary) will allow you to enjoy the benefits of the strong typing, whereas using a more generic type will allow you to be more dynamic. Really it depends on what you intend to use the class for.

How to add a transient NSIndexPath property to NSManagedObject

I mean to add a property of type NSIndexPath to my NSManagedObject but it doesn't seem to be one of the recognized property list types. I also mean to make it transient since index paths change depending on the UI, hence I have no reason to save it in the managed document.
I'm thinking of creating two separate NSNumber properties called section and row instead but it'll be much easier if I had an NSIndexPath instead. Help?
Just make it a transformable attribute with no value transformer name. The default transformer-- NSKeyedUnarchiveFromDataTransformerName-- takes any class that conforms to the NSCoding protocol and saves it as NSData.
Works for me with NSIndexPath, NSArray, and NSDictionary. The accessors just work... I believe by setting and getting an id type, so it's not as typesafe as an NSIndexSet* property would be, but it's good enough.
[edit...]
Err, actually. I use Mogenerator, which may take care of the issue mentioned in the docs:
In principle, you don’t have to do anything else. In practice, to suppress compiler warnings you should declare a property for the attribute...
... it's Mogenerator that makes a property of type id. The Apple example creates a property of the specific type in the entity class.

NSUserDefaults and primitive data types?

What is the point of the NSUserDefaults methods such as -setFloat:forKey: and -floatForKey: when -registerDefaults: accepts only a NSDictionary which can't hold any primitive data types - only objects.
Instead it seems I have to use -setObject:forKey and -objectForKey: and store only NSNumber objects if I want to be able to give my floats any actual default values.
What am I missing here?
setFloat: is just a convenience method that creates an NSNumber and then passes that to setObject:. floatForKey: does the reverse.
NSDictionary can only hold object types, so you need to wrap primitives in the appropriate objects. So yes, you do need to do what you are doing to set up the default defaults.
It would be nice if you could use those methods directly on an NSDictionary, that would be a pretty trivial category to write.

NSMutableDictionary doesn't get written to file

I have NSMutableDictionary object say obj. When I write it to the disk using
[obj writeToFile:filename atomically:YES] , the file does not get written to the disk. But the same set of statements work for a smaller mutable dictionary.
The first obj is (nonatomic, retain) property object of a class. The second smaller obj is a temporary local variable.
But the same set of statements work
for a smaller mutable dictionary.
That sets off a warning bell. Namely, when you are attempting to write the large dictionary to disk, what is in it? If you are using any of NSDictionary's file writing methods, they will only work with dictionaries that only contain instances of the classes blessed for use in property lists.
That is, if you have random other classes in there, the dictionary will not be written. Doesn't matter of the classes support NSCoding or not.
If you need to persist a dictionary with non-property list classes, you'll either need to use NSCoding or, more likely better, use Core Data.
This should work. Have you checked that obj isn't nil by some accident?

Resources