This question can be a duplicated one. But I was unable to find a proper answer for my issue.
I have following xml file downloading from a server.
<INCIDENTTYPES>
<INCIDENT FORMNAME="first" TEXT="First incident">
<TYPE>Type1</TYPE>
<TYPE>Type2</TYPE>
<TYPE>Type3 Tag</TYPE>
<TYPE>Type4 Tag</TYPE>
<LOCATION>Council</LOCATION>
<LOCATION>Domestic</LOCATION>
<LOCATION>Commercial</LOCATION>
</INCIDENT>
<INCIDENT FORMNAME="second" TEXT="Second incident">
<TYPE>Second type</TYPE>
<TYPE>Second/first type</TYPE>
<TYPE>Second3</TYPE>
<LOCATION>Council</LOCATION>
<LOCATION>Domestic</LOCATION>
<LOCATION>Commercial</LOCATION>
</INCIDENT>
</INCIDENTTYPES>
I am using RaptureXML to parse the xml file and parsing can be done as follows.
RXMLElement *rootXML = [RXMLElement elementFromXMLData:self.connectionData];
[rootXML iterate:#"INCIDENT" usingBlock: ^(RXMLElement *incidents) {
if([[incidents attribute:#"FORMNAME"] isEqualToString:#"first"]){
NSArray *listArray = [NSArray array];
listArray = [incidents children:#"TYPE"];
IncidentData *iData = [[IncidentData alloc] init];
[iData.type setValue:listArray forKey:#"type"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:iData];
[self.userDefault setObject:data forKey:#"firstObject"];
}
}
The IncidentData class as follows.
#import "IncidentData.h"
#implementation IncidentData
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super init]) {
//self.type is an array
self.type = [aDecoder decodeObjectForKey:#"type"];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder{
[aCoder encodeObject:self.type forKey:#"type"];
}
#end
I am trying to load data as following.
NSData *dd = [self.userDefault objectForKey:#"firstObject"];
IncidentData *items = (IncidentData *)[NSKeyedUnarchiver unarchiveObjectWithData:dd];
NSArray *typeArray = [items.type objectAtIndex:0];
NSLog(#"Incident type : %#", typeArray);
But typeArray is null.
Summary: I am trying to parse a remote xml file and save the values on to the disk and use later stage of the app.
Can you please help me on this ?
RaptureXML, RXMLElement might not support NSCoding.
try substituting:
listArray = [incidents children:#"TYPE"];
with:
listArray = [[incidents children:#"TYPE"] valueForKeyPath:#"text"];
Related
The requirement is that I want to store NSArray of my custom objects in NSUserDefaults.
Following is the code from my example
- (void)viewDidLoad
{
[super viewDidLoad];
sampleArray=[[NSMutableArray alloc]init];
MyClass *obj1=[[MyClass alloc]init];
obj1.name=#"Reetu";
obj1.countOpen=1;
NSArray *subArray = [[NSArray alloc]initWithObjects:#"likes131",#"likes132", #"likes133", nil];
obj1.hobbies = [[NSArray alloc]initWithObjects:#"like11", #"like12", subArray, nil];
[sampleArray addObject:obj1];
MyClass *obj2=[[MyClass alloc]init];
obj2.name=#"Pinku";
obj2.countOpen=2;
NSArray *subArray2 = [[NSArray alloc]initWithObjects:obj1 ,#"likes231",#"likes232", #"likes233", obj1 ,nil];
obj2.hobbies = [[NSArray alloc]initWithObjects:#"like21", #"like22", subArray2 ,nil];
[sampleArray addObject:obj2];
MyClass *obj3=[[MyClass alloc]init];
obj3.name=#"Mike";
obj3.countOpen=6;
obj3.hobbies = [[NSArray alloc]initWithObjects:obj1 , obj2 ,#"likes000", nil];
[sampleArray addObject:obj3];
//First lets encode it
NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:sampleArray];
[userDefault setObject:myEncodedObject forKey:[NSString stringWithFormat:#"sample"]];
[userDefault synchronize];
//Lets decode it now
NSData *myDecodedObject = [userDefault objectForKey: [NSString stringWithFormat:#"sample"]];
NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: myDecodedObject];
//Print the array received from User's Default
for (MyClass *item in decodedArray) {
NSLog(#"name=%#",item.name);
NSLog(#"LIKES TO %#",item.hobbies);
}
}
This is my custom class confirming to the NSCoding protocol
- (void)encodeWithCoder:(NSCoder *)encoder
{
//Encode properties, other class variables, etc
[encoder encodeObject:self.name forKey:#"name"];
[encoder encodeObject:[NSNumber numberWithInt:self.countOpen] forKey:#"destinationCode"];
[encoder encodeObject:self.hobbies forKey:#"likesTo"];
}
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if( self != nil )
{
self.name = [decoder decodeObjectForKey:#"name"];
self.countOpen = [[decoder decodeObjectForKey:#"countOpen"] intValue];
self.hobbies = [decoder decodeObjectForKey:#"likesTo"];
}
return self;
}
here is the output:-
2013-10-22 17:01:47.118 Sample[1056:c07] name=Reetu
2013-10-22 17:01:47.120 Sample[1056:c07] LIKES TO (
like11,
like12,
(
likes131,
likes132,
likes133
)
)
2013-10-22 17:01:47.121 Sample[1056:c07] name=Pinku
2013-10-22 17:01:47.123 Sample[1056:c07] LIKES TO (
like21,
like22,
(
"<MyClass: 0x6e32910>",
likes231,
likes232,
likes233,
"<MyClass: 0x6e32910>"
)
)
2013-10-22 17:01:47.125 Sample[1056:c07] name=Mike
2013-10-22 17:01:47.127 Sample[1056:c07] LIKES TO (
"<MyClass: 0x6e32910>",
"<MyClass: 0x6e1f610>",
likes000
)
The problem is <MyClass: 0X632910>. I was expecting it to be contents of obj1 itself.
The problem isn't with NSUserDefaults. It's with how you are printing the information out:
You should override -(NSString*) description, probably to read something like this:
-(NSString*) description
{
return [NSString stringWithFormat:#"<%# - name:%# open:%d>", self.class self.name, self.countOpen];
}
You are not logging the way like you are adding the elements to the array. You are adding a MyClass object to the second array but you are expecting its hobbies NSArray to be printed.
Change your logging function like this. It will print corretly until the second object. For the third object you have to write another for loop in the function. Because your object hierarchy is like that.
for (MyClass *item in decodedArray) {
NSLog(#"name=%#",item.name);
if ([item.technologies isKindOfClass:[MyClass class]]) {
for (MyClass *item in arr) {
NSLog(#"name=%#",item.name);
NSLog(#"LIKES TO %#",item.hobbies);
}
}
else{
NSLog(#"LIKES TO %#",item.hobbies);
}
}
I want save bool property to my file, and I did it in my opinion is barbaric. I have to check my property and then add string to NSMutableArray. Can I some how check property name, state/value and then save to file? Or maybe I should use XML file for this? But still for efficient use I should get property name and state/value.
Could you give me some advice?
-(void) saveSettings
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"settings" ofType:#""];
if (music)
{
[correctSettingArray removeObjectAtIndex:0];
[correctSettingArray addObject:#"music = 1"];
}
else
{
[correctSettingArray removeObjectAtIndex:0];
[correctSettingArray addObject:#"music = 0"];
}
if (sfx)
{
[correctSettingArray removeObjectAtIndex:1];
[correctSettingArray addObject:#"sfx = 1"];
}
else
{
[correctSettingArray removeObjectAtIndex:0];
[correctSettingArray addObject:#"sfx = 0"];
}
if (vibration)
{
[correctSettingArray removeObjectAtIndex:0];
[correctSettingArray addObject:#"vibration = 1"];
}
else
{
[correctSettingArray removeObjectAtIndex:0];
[correctSettingArray addObject:#"vibration = 0"];
}
[correctSettingArray writeToFile:path atomically:true];
}
Thanks in Advance.
if you want to save simple application settings like this use NSUserDefaults
[[NSUserDefaults standardUserDefaults] setBool:vibrationBool forKey:#"vibrationKey"];
then when you want to read it
BOOL vibrationBool = [[NSUserDefaults standardUserDefaults] boolForKey:#"vibrationKey"];
I think you can save as NSNumber using this...
[NSNumber numberWithBool:BOOLATR]
and retrieve the value doing...
BOOLATR = [[correctSettingArray objectAtIndex:X] boolValue]
In any case, you could prefer to use NSMutableDictionary for variable matching instead an array.
[dictionary setValue:[NSNumber numberWithBool:BOOLATR] forKey:#"BOOLATR"];
&
BOOLATR = [[dictionary valueForKey:#"BOOLATR"] boolValue]
For what you ask — saving user settings — you should use NSUserDefaults as described in answer by wattson12.
If you really need to save boolean properties to file, given you are working with Objective-C objects, easiest way would be to use archive and serialize your data structure by implementing the NSCoding protocol. See Apple's Archives and Serializations Programming Guide.
The NSCoding protocol has two parts: initWithCoder is basically another constructor for your object:
- (id)initWithCoder:(NSCoder *)decoder
{
self = [super init];
if (self) {
if ([decoder containsValueForKey:#"sunNeverSet"])
self.sunNeverSet = [NSNumber numberWithBool:
[decoder decodeBoolForKey:#"sunNeverSet"]];
}
return self;
}
The encodeWithCoder is the serialization:
- (void)encodeWithCoder:(NSCoder *)coder
{
if (sunNeverRise) [coder encodeBool:[sunNeverRise boolValue]
forKey:#"sunNeverRise"];
}
Then you would encode your object graph into platform-independent byte stream (ie. NSData) using the NSKeyedArchiver and write the data to file.
NSMutableData *data = [[NSMutableData alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]
initForWritingWithMutableData:data];
[archiver encodeRootObject:myObjectImplementingNSCoding];
[archiver finishEncoding];
[data writeToFile:path atomically:YES];
To read it back, you'll decode the data using NSKeyedUnarchiver and get back your object graph.
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc]
initForReadingWithData:data];
id myObjectImplementingNSCoding = [[unarchiver decodeObject] retain];
[unarchiver finishDecoding];
According to this post I can use the encryption/decryption methods to store/retrieve plist file securely.
But the problem is:
Q: After I have decrypted the plist file, how can I parse and store the plist file as NSDictrionary object
Probably NSPropertyListSerialization is what you are looking for.
As seen in this Post:
Plist Array to NSDictionary
You could use core foundation approach here with the method CFPropertyListCreateFromXMLData
If the plist represents the NSDictionary content, the following check should be passed:
if ([(id)plist isKindOfClass:[NSDictionary class]])
and the plist object might be safely casted to NSDictionary. If no, something is wrong with the data or decription process.
The easiest way would be creating a category for NSDictionary like this:
NSDictionaryWithData.h:
#interface NSDictionary (NSDictionaryWithData)
+ (id)dictionaryWithData:(NSData *)data;
- (id)initWithData:(NSData *)data;
#end
NSDictionaryWithData.m:
#implementation NSDictionary (NSDictionaryWithData)
+ (id)dictionaryWithData:(NSData *)data
{
return [[[NSDictionary alloc] initWithData:data] autorelease];
}
- (id)initWithData:(NSData *)data
{
self = (NSDictionary *)[NSPropertyListSerialization propertyListFromData:data
mutabilityOption:NSPropertyListImmutable
format:NULL
errorDescription:nil];
return [self retain];
}
#end
Usage:
NSDictionary* myDict = [[NSDictionary alloc] initWithData:decryptedData];
One of the possible reasons dictionaryWithData doesn't exist is a property list is not necessarily a dictionary at the root level. It could equally be an NSArray.
Here is my take on a solution: a category that utilises NSPropertyListSerialization
Features
Silently discards data that contains arrays at the root level.
Checks which method to use ( propertyListFromData:mutabilityOption:format:errorDescription: is depreciated )
NSMutableDictionary also supported
Note - this takes an unorthodox approach of wrapping a class factory method with an init method. This is for efficiency - most of the time you will be using the factory method, which just wraps NSPropertyListSerialization, which internally invokes alloc/init/autorelease to return an appropriate object.
NSDictionary+DictionaryWithData.h
#import <Foundation/Foundation.h>
#interface NSDictionary (DictionaryWithData)
+ (id)dictionaryWithData:(NSData *)data;
- (id)initWithData:(NSData *)data;
#end
NSDictionary+DictionaryWithData.m
#import "NSDictionary+DictionaryWithData.h"
#implementation NSDictionary (DictionaryWithData)
+(NSPropertyListMutabilityOptions) mutabilityOption {
return NSPropertyListImmutable;
}
+ (id)dictionaryWithData:(NSData *)data
{
static BOOL methodChecked = NO;
static BOOL use_propertyListWithData = NO;
if (!methodChecked) {
SEL sel = #selector(propertyListWithData:options:format:error:);
use_propertyListWithData = [[NSPropertyListSerialization class]
respondsToSelector:sel];
methodChecked = YES;
}
id result;
if (use_propertyListWithData) {
result = [NSPropertyListSerialization propertyListWithData:data
options:[self mutabilityOption]
format:nil
error:nil];
} else {
result = [NSPropertyListSerialization propertyListFromData:data
mutabilityOption:[self mutabilityOption]
format:NULL
errorDescription:nil];
}
return [result isKindOfClass:[NSDictionary class]] ? result : nil;
}
- (id)initWithData:(NSData *)data
{
id result = [[self class] dictionaryWithData:data];
self = result ? [self initWithDictionary:result ] : nil;
return self;
}
#end
#implementation NSMutableDictionary (DictionaryWithData)
+(NSPropertyListMutabilityOptions) mutabilityOption {
return NSPropertyListMutableContainersAndLeaves;
}
#end
I am trying to save my object graph to a file and then reload it at a later time, however decodeObjectForKey: always returns nil for any key I specify.
A binary file is created and does have the occasional human readable text in it, i.e., titleTextColor so I think the archiving process is working.
Have I miss-understood how NSKeyedArchiver and NSKeyedUnarchiver work? Any help would be appreciated.
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeFloat:titleFontSize forKey:#"titleFontSize"];
[encoder encodeObject:[UIColor orangeColor] forKey:#"titleTextColor"];
[encoder encodeObject:lineSeparatorColor forKey:#"lineSeparatorColor"];
[encoder encodeObject:bodyTextColor forKey:#"bodyTextColor"];
[encoder encodeFloat:bodyTextFontSize forKey:#"bodyTextFontSize"];
[encoder encodeObject:backgroundColor forKey:#"backgroundColor"];
[encoder encodeObject:tintColor forKey:#"tintColor"];
[encoder encodeInteger:bodyTextAlignment forKey:#"bodyTextAlignment"];
[encoder encodeObject:#"Text" forKey:#"Text"];
}
+ (void) saveToFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Serialise the object
NSData *serializedObject = [NSKeyedArchiver archivedDataWithRootObject:sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
// Write the defaults to a file
if (serializedObject) [serializedObject writeToFile:pathAndFileName atomically:YES];
}
+ (void) loadFromFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
NSKeyedUnarchiver *defaults = [[NSKeyedUnarchiver alloc] initForReadingWithData:codedData];
// Set the properties of the shared instance
NSString *test = [defaults decodeObjectForKey:#"Text"];
NSLog (#"%#", test);
sharedInstance.titleTextColor = [defaults decodeObjectForKey:#"titleTextColor"];
[defaults release];
}
EDIT: Based on advice from DarkDust:
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
self.titleFontSize = [[aDecoder decodeObjectForKey:#"titleFontSize"] floatValue];
self.titleTextColor = [aDecoder decodeObjectForKey:#"titleTextColor"];
self.lineSeparatorColor = [aDecoder decodeObjectForKey:#"lineSeparatorColor"];
self.bodyTextColor = [aDecoder decodeObjectForKey:#"bodyTextColor"];
self.bodyTextFontSize = [[aDecoder decodeObjectForKey:#"bodyTextFontSize"] floatValue];
self.backgroundColor = [aDecoder decodeObjectForKey:#"backgroundColor"];
self.tintColor = [aDecoder decodeObjectForKey:#"tintColor"];
self.bodyTextAlignment = [[aDecoder decodeObjectForKey:#"bodyTextAlignment"] intValue];
}
return self;
}
and creating a new instance just to test:
+ (void) loadFromFile {
// Get the shared instance
PSYDefaults *sharedInstance = [PSYDefaults sharedInstance];
// Get the path and filename of the file
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pathAndFileName = [documentsDirectory stringByAppendingPathComponent:ksDefaultsFileName];
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
PSYDefaults *newInstance = [NSKeyedUnarchiver unarchiveObjectWithData:codedData];
sharedInstance.titleTextColor = newInstance.titleTextColor;
}
EDIT - Update (needed to encode floats and ints as NSNumbers)
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[NSNumber numberWithFloat:titleFontSize] forKey:#"titleFontSize"];
[encoder encodeObject:titleTextColor forKey:#"titleTextColor"];
[encoder encodeObject:lineSeparatorColor forKey:#"lineSeparatorColor"];
[encoder encodeObject:bodyTextColor forKey:#"bodyTextColor"];
[encoder encodeObject:[NSNumber numberWithFloat:bodyTextFontSize] forKey:#"bodyTextFontSize"];
[encoder encodeObject:backgroundColor forKey:#"backgroundColor"];
[encoder encodeObject:tintColor forKey:#"tintColor"];
[encoder encodeObject:[NSNumber numberWithInt:bodyTextAlignment] forKey:#"bodyTextAlignment"];
}
You serialized using a single root object, but you try to deserialize using a key which doesn't exist at that level.
You want unarchiveObjectWithData:, as in:
NSData *codedData = [[[NSData alloc] initWithContentsOfFile:pathAndFileName] autorelease];
PSYDefaults *decodedDefaults = [NSKeyedUnarchiver unarchiveObjectWithData:codedData];
Note that you'll also need to implement initWithCoder: as counterpart to encodeWithCoder:. Even though it seems you want to have a singleton here, NSCoding demands to create a new object here due to [NSKeyedArchiver archivedDataWithRootObject:sharedInstance].
If you want to en/decode the fields without creating a new instance of PSYDefaults, then you need to use -[NSKeyedArchiver initForWritingWithMutableData:] and pass that archive to a method similar to your encodeWithCoder: (but you should give it a different name then). Then you'd write a counterpart which reads the fields back via a NSKeyedUnarchiver where you do use decodeObjectForKey: and friends for each field.
You also might want to read Apple's Archives and Serializations Programming Guide.
Try to save your object using:
[NSKeyedArchiver archiveRootObject:object toFile:filePath];
and load it using:
[NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
I use above methods to save NSDictionary with custom object to a file.
And also you should have the function initWithCoder:(NSCoder *)decoder in your object.
Which decode the data using
[decoder decodeObjectFoyKey:yourKey];
I had another problem with NSCoder's decodeObjectForKey method while using FXForm - it crashed without any explanation.
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
self.someObject = [decoder decodeObjectForKey:#"someObject"];
}
return self;
}
The reason was in memory issues. Commonly, looks like when there is no explanation of a bug in logs, it means, it's a memory issue. I forgot to use correct property attribute - copy. I used assign instead. This is correct code:
#interface MyClass : : NSObject <FXForm, NSCoding>
#property (nonatomic, copy) SomeClass *someObject;
#end
Just in case somebody meets this problem too.
I am having an issue in converting a NSObject into NSData. I have a class which inherits NSObject.
When i tried to convert the object of that particular class into NSData as follows :
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];
but it gives out exception stating that -[classObject encodeWithCoder:]: unrecognized selector sent to instance ..
I have also added the object to a newly created array as
NSMutableArray *wrapperedData = [NSMutableArray arrayWithObject: classObject];
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:value];
But still , its giving out exception.
So I need to extract the bytes from the object classObject.
Any help would be greatly appreciated ...
awaiting for your reply ...
You must implement for your own object such as:
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.name forKey:#"name"];
[aCoder encodeInt:self.age forKey:#"age"];
[aCoder encodeObject:self.email forKey:#"email"];
[aCoder encodeObject:self.password forKey:#"password"];
}
BOOL success = [NSKeyedArchiver archiveRootObject:person toFile:archiveFilePath];
and:
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.name = [aDecoder decodeObjectForKey:#"name"];
self.age = [aDecoder decodeIntForKey:#"age"];
self.email = [aDecoder decodeObjectForKey:#"email"];
self.password = [aDecoder decodeObjectForKey:#"password"];
}
return self;
}
Person *unarchivePerson = [NSKeyedUnarchiver unarchiveObjectWithFile:archiveFilePath];
You need to implement encodeWithCoder: on your custom class, serializing all of its attributes using the NSCoder passed into it. If its attributes include any more custom classes, they'll need encodeWithCoder: implementing too.
Instead of
NSData *dataOnObject = [NSKeyedArchiver archivedDataWithRootObject:classObject];
it should be
NSData *dataOnObject = [[NSUserDefaults standardUserDefaults] objectForKey:#"someKey"];
But that's just for reading data in that's already been saved. If you want to save an object as NSData then you have this:
[[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:classObject] forKey:#"someKey"];
But that's not all. Your classObject has to implement the NSCoding protocol and have the two methods encodeWithCoder: and initWithCoder: since it's not an NS object in order for it to work.
you can only archive objects that support the NSCoding protocol
You can convert any object to NSData with the NSCoding protocol.
You can find sample code to do this here:
http://samsoff.es/posts/archiving-objective-c-objects-with-nscoding
This is a example of custom object converted to NSData (so it can be then saved into user defaults)
Create the following files:
Catalog.h
#interface Catalog : NSObject
#property (nonatomic, assign) int pk;
#property (nonatomic, copy) NSString *catalogName;
#property (nonatomic, copy) NSString *catalogDescription;
#property (nonatomic, assign) int catalogEdition;
#property (nonatomic, assign) int catalogTotalPages;
- (void)encodeWithCoder:(NSCoder *)aCoder;
- (id)initWithCoder:(NSCoder *)aDecoder;
#end
Catalog.m
#import <Foundation/Foundation.h>
#import "Catalog.h"
#implementation Catalog
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.catalogName forKey:#"catalogName"];
[aCoder encodeObject:self.catalogDescription forKey:#"catalogDescription"];
[aCoder encodeInt:self.catalogEdition forKey:#"catalogEdition"];
[aCoder encodeInt:self.catalogTotalPages forKey:#"catalogTotalPages"];
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super init]) {
self.catalogName = [aDecoder decodeObjectForKey:#"catalogName"];
self.catalogDescription = [aDecoder decodeObjectForKey:#"catalogDescription"];
self.catalogEdition = [aDecoder decodeIntForKey:#"catalogEdition"];
self.catalogTotalPages = [aDecoder decodeIntForKey:#"catalogTotalPages"];
}
return self;
}
#end
Finally in your controller include header files
#import "Catalog.h"
And add this code to use your object (in this case im saving into user defaults)
Catalog *catalog = [[Catalog alloc] init];
catalog.catalogName = #"catalogName";
catalog.catalogDescription = #"catalogName";
catalog.catalogEdition = 1;
NOTE: in this line of code is where the actual data passing is taking place
//archiving object to nsdata
NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:catalog];
[[NSUserDefaults standardUserDefaults] setObject:encodedObject forKey:#"keyName"];
[[NSUserDefaults standardUserDefaults] synchronize];
In case you want to get your object back from NSData
NSData *nsData = [[NSUserDefaults standardUserDefaults] objectForKey:#"keyName"];
//unarchiving object to nsdata
Catalog *selectedCatalog = [NSKeyedUnarchiver unarchiveObjectWithData: nsData];
Hope this helps!