How can I save a Swift dictionary structure? - ios

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:

Related

How do I save a custom c++ class object to NSUserDefaults?

I want to add a C++ Class object into NSUserDefaults. If I add it directly, it crashes.
How do I add c++ Class object to NSUserDefaults?
NSUserDefaults supports some NSObject-based classes to be encoded out of the box. Proper way to save custom NSObject classes into NSUserDefaults instance is to encode them into NSData and save it.
In your case, since you have a C++ class, you could either wrap it's data to an NSObject (NSDictionary maybe) or implement a class <-> string serialisation and deserialisation, saving a string object into the NSUserDefaults instance.

Initialize a subclass of NSManagedObject

I have a question about CoreData and NSManagedObject.
I receive a NSDictionary in my ClientRESTClass (I use AFNetworking 2.0) so I have a Json data in this NSDictionary.
For this object type I use a my protocol with two methods that these objects must implement:
- encodeFromJson //(instance to JSON)
- decodeFromJson //(from json I create an instance)
Now I have a myObj as subclass of NSManageObject that implements this protocol.
1) In the decodeFromJson how can I to generate an instance of myObj? Is necessary to use in this point a context? Is possible to use a simple init?
2) At this level I receive data from server an I create instance of these object. I pass this instance to the caller and he will decide whether to save the object or if you do not save it in CoreData.
So, If I have to use a contex, how can I discard objects that I placed in the context?
You should not create an NSManagedObject directly, you should use the NSNSEntityDescription's insertNewObjectForEntityForName -- see: Apple Docs.

How do I control what objects to encode using NSKeyedArchiver?

I have an array filled with two different types of custom classes. Lets call them ClassA and ClassB.
I want to enabled encoding/serialization for ClassA, but not for ClassB.
I am using [NSKeyedArchiver archiveRootObject:toFile] to serialize the list to disk.
I want NSKeyedArchiver to ignore all objects of type ClassB.
I dont want to iterate though the list and remove all ClassB objects, as I want to keep the original list in memory.
You can either subclass NSArray and override the -encodeWithCoder: method or copy and filter the original and then archive the copy rather than the original.

How to store custom object in User Defaults - 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 :)

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.

Resources