This question already has answers here:
Issue : Convert an Object to json in iOS
(4 answers)
Closed 9 years ago.
I have one main entity class with name "Store" like :
Store.h :-
#import <Foundation/Foundation.h>
#import "SignIn.h"
#interface Store : NSObject
#property (nonatomic, retain) NSString *storeId;
#property (nonatomic, retain) NSString *storeProfileId;
#property (nonatomic, retain) NSString *storeName;
#property (nonatomic, retain) NSString *storeRegion;
#property (nonatomic, retain) SignIn *signIn;
#end
Store.m :-
#import "Store.h"
#implementation Store
#synthesize storeId, storeProfileId, storeName, storeRegion, signIn;
- (id) initWithCoder: (NSCoder *)coder
{
self = [[Store alloc] init];
if (self != nil)
{
self.storeId = [coder decodeObjectForKey:#"storeId"];
self.storeProfileId = [coder decodeObjectForKey:#"storeProfileId"];
self.storeName = [coder decodeObjectForKey:#"storeName"];
self.storeRegion = [coder decodeObjectForKey:#"storeRegion"];
self.signIn = [coder decodeObjectForKey:#"signIn"];
}
return self;
}
- (void)encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:storeId forKey:#"storeId"];
[coder encodeObject:storeProfileId forKey:#"storeProfileId"];
[coder encodeObject:storeName forKey:#"storeName"];
[coder encodeObject:storeRegion forKey:#"storeRegion"];
[coder encodeObject:signIn forKey:#"signIn"];
}
#end
Here in Store class, i am taking one more class name "Sign In", that include some other attributes.
SignIn.h :-
#import <Foundation/Foundation.h>
#interface SignIn : NSObject
#property (nonatomic, retain) NSString *inTime;
#property (nonatomic, retain) NSString *outTime;
#property (nonatomic, retain) NSString *isStatus;
#end
SignIn.m :-
#import "SignIn.h"
#implementation SignIn
#synthesize inTime, outTime, isStatus;
- (id) initWithCoder: (NSCoder *)coder
{
self = [[SignIn alloc] init];
if (self != nil)
{
self.inTime = [coder decodeObjectForKey:#"inTime"];
self.outTime = [coder decodeObjectForKey:#"outTime"];
self.isStatus = [coder decodeObjectForKey:#"isStatus"];
}
return self;
}
- (void)encodeWithCoder: (NSCoder *)coder
{
[coder encodeObject:inTime forKey:#"inTime"];
[coder encodeObject:outTime forKey:#"outTime"];
[coder encodeObject:isStatus forKey:#"isStatus"];
}
#end
Now i need to post this Store object on server. So I am creating dictionary using below code :
NSMutableArray *storeJSONArray=[NSMutableArray array];
for (Store *store in array1) {
NSMutableDictionary *storeJSON=[NSMutableDictionary dictionary];
[storeJSON setValue:store.storeId forKey:#"storeId"];
[storeJSON setValue:store.storeProfileId forKey:#"storeProfileId"];
[storeJSON setValue:store.storeName forKey:#"storeName"];
[storeJSON setValue:store.storeRegion forKey:#"storeRegion"];
//Sign In
[storeJSON setValue:store.signIn.inTime forKey:#"inTime"];
[storeJSON setValue:store.signIn.outTime forKey:#"outTime"];
[storeJSON setValue:store.signIn.isStatus forKey:#"isStatus"];
[storeJSONArray addObject:storeJSON];
}
NSMutableDictionary *dictionnary = [NSMutableDictionary dictionary];
[dictionnary setObject:storeJSONArray forKey:#"Store"];
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionnary
options:kNilOptions
error:&error];
if (! jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
But as an output, i am getting jsonString value like :
{
"Store": [
{
"storeId": "SGVM0001",
"storeProfileId": "SG-12",
"store_name": "Best Denki",
"storeRegion": "Ngee Ann City",
"inTime": "2013-12-05 11:03:00",
"outTime": "2013-12-0511: 27: 00",
"isStatus": "YES"
}
]
}
But i need an output as :
{
"Store": [
{
"storeId": "SGVM0001",
"storeProfileId": "SG-12",
"store_name": "Best Denki",
"storeRegion": "Ngee Ann City",
"signIn": {
"inTime": "2013-12-05 11:03:00",
"outTime": "2013-12-0511: 27: 00",
"isStatus": "YES"
}
}
]
}
Can you please check my code and let me know what changes i need to do here for getting above output ?
Thanks
Then you need to create one more dictionary
NSDMutableDict *signInDic = [NSMutableDictionary dictionary];
//Sign In
[signInDic setValue:store.signIn.inTime forKey:#"inTime"];
[signInDic setValue:store.signIn.outTime forKey:#"outTime"];
[signInDic setValue:store.signIn.isStatus forKey:#"isStatus"];
[storeJSON setObject:signInDic forKey:#"sign_in"];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setValue:store.dict.inTime forKey:#"inTime"];
.......
.....
[storeJSON setObject:dict forKey:#"sign_in"];
Related
I have created a program to retrieve JSON file and it achieved it
NSString *FilePath = [[NSBundle mainBundle]pathForResource:#"Message" ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:FilePath];
NSError *error;
if(error){
NSLog(#"Error and CAn't retrive data: %#", error.localizedDescription);
}else{
NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSLog(#"Your Json Dictionary values are %#", jsonDict);
for(NSDictionary *valuesDictionary in jsonDict){
ShopCollectionObject *shopObject = [[ShopCollectionObject alloc]initWithID:[[valuesDictionary objectForKey:#"message_id"]integerValue] Name:[valuesDictionary objectForKey:#"product"] TimeAsPrice:[[valuesDictionary objectForKey:#"message_time"]integerValue] Avathar:[valuesDictionary objectForKey:#"item_image"] user:[valuesDictionary objectForKey:#"user_image"] Name_User:[valuesDictionary objectForKey:#"user_name"] LocationOfUser:[valuesDictionary objectForKey:#"locate_user"]];
But My app crashes here with the above error
[self.objectForArray addObject:shopObject];
}
}
Updated my shop collection code below
Shopcollection object.h
#import <Foundation/Foundation.h>
#interface ShopCollectionObject : NSObject
-(instancetype) initWithID: (int)msgID Name:(NSString *)Profile_name TimeAsPrice:(int) GivenTimeAsPrice Avathar:(NSString *) PhotoOfAvathar user:(NSString *)UserAvathar Name_User: (NSString *) UserNames LocationOfUser:(NSString *) USerLocationGiven;
#property (nonatomic) int msgID;
#property(nonatomic, strong)NSString* Name;
#property (nonatomic) int TimeAsPrice;
#property (nonatomic,strong) NSString* Avathar;
#property (nonatomic,strong) NSString* user;
#property (nonatomic,strong) NSString* Name_User;
#property(nonatomic,strong) NSString* LocationOfUser;
#end
Shopcollectionobject.m
#import "ShopCollectionObject.h"
#implementation ShopCollectionObject
-(instancetype)initWithID:(int)msgID Name:(NSString *)Profile_name TimeAsPrice:(int)GivenTimeAsPrice Avathar:(NSString *)PhotoOfAvathar user:(NSString *)UserAvathar Name_User:(NSString *)UserNames LocationOfUser:(NSString *)USerLocationGiven{
self = [super init];
if(self){
self.msgID = msgID;
self.Name = Profile_name;
self.TimeAsPrice = GivenTimeAsPrice;
self.Avathar = PhotoOfAvathar;
self.user = UserAvathar;
self.Name_User = UserNames;
self.LocationOfUser = USerLocationGiven;
}
return self;
}
#end
You likely aren't initializing your objectForArray. So when you try to call addObject, it's calling it on a null object.
ShopCollectionObject.h
#import <Foundation/Foundation.h>
#interface ShopCollectionObject : NSObject
#property (nonatomic) int message_id;
#property (strong, nonatomic) NSString *Name;
#property (nonatomic) int TimeAsPrice;
#property (strong, nonatomic) NSString *Avathar;//user,Name_User,LocationOfUser,message_id
#property (strong, nonatomic) NSString *user;
#property (strong, nonatomic) NSString *Name_User;
#property (strong, nonatomic) NSString *LocationOfUser;
-(instancetype) initWithID: (int)msgID Name:(NSString *)Profile_name TimeAsPrice:(int) GivenTimeAsPrice Avathar:(NSString *) PhotoOfAvathar user:(NSString *)UserAvathar Name_User: (NSString *) UserNames LocationOfUser:(NSString *) USerLocationGiven;
#property (nonatomic) int msgID;
#end
ShopCollectionObject.m
#import "ShopCollectionObject.h"
#implementation ShopCollectionObject
-(instancetype)initWithID:(int)msgID Name:(NSString *)Profile_name TimeAsPrice:(int)GivenTimeAsPrice Avathar:(NSString *)PhotoOfAvathar user:(NSString *)UserAvathar Name_User:(NSString *)UserNames LocationOfUser:(NSString *)USerLocationGiven{
self = [super init];
if(self){
self.msgID = msgID;
self.Name = Profile_name;
self.TimeAsPrice = GivenTimeAsPrice;
self.Avathar = PhotoOfAvathar;
self.user = UserAvathar;
self.Name_User = UserNames;
self.LocationOfUser = USerLocationGiven;
}
return self;
}
#end
ViewController.m
#import "ViewController.h"
#import "ShopCollectionObject.h"
#interface ViewController ()
{
NSMutableArray *objectForArray;
}
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
objectForArray = [[NSMutableArray alloc]init];
NSString *FilePath = [[NSBundle mainBundle]pathForResource:#"Message" ofType:#"json"];
NSData *data = [NSData dataWithContentsOfFile:FilePath];
NSError *error;
if(error){
NSLog(#"Error and CAn't retrive data: %#", error.localizedDescription);
}else{
NSDictionary * jsonDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
for(NSDictionary *valuesDictionary in jsonDict){
ShopCollectionObject *shopObject = [[ShopCollectionObject alloc]initWithID:[[valuesDictionary objectForKey:#"message_id"]intValue] Name:[valuesDictionary objectForKey:#"product"] TimeAsPrice:[[valuesDictionary objectForKey:#"message_time"]intValue] Avathar:[valuesDictionary objectForKey:#"item_image"] user:[valuesDictionary objectForKey:#"user_image"] Name_User:[valuesDictionary objectForKey:#"user_name"] LocationOfUser:[valuesDictionary objectForKey:#"locate_user"]];
[objectForArray addObject:shopObject];
}
NSLog(#"%#",objectForArray);
ShopCollectionObject *data = objectForArray[0];
NSLog(#"%#",data.Name);
}
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
pls check this code
I have a NSMutableArray filled with objects of my Movie class wich i want to save but it doesn't work and i can not figure out why...
Movie.h:
#interface Movie : NSObject <NSCoding>{
NSString *name;
int year;
int length;
NSString *file_size;
int rating;
NSArray *genre;
NSString *plot;
}
#property (nonatomic, retain) NSString *name;
#property (nonatomic, assign) int year;
#property (nonatomic, assign) int length;
#property (nonatomic, retain, retain) NSString *file_size;
#property (nonatomic, assign) int rating;
#property (nonatomic, retain) NSArray *genre;
#property (nonatomic, retain) NSString *plot;
-(id) initWithName:(NSString*)newName year:(int)newYear length:(int)newLength filesize:(NSString*)newFileSize rating:(int)newRating genre:(NSArray*)newGenre plot:(NSString*)newPlot;
- (void) encodeWithCoder : (NSCoder *)encode ;
- (id) initWithCoder : (NSCoder *)decode;
#end
Movie.m:
#implementation Movie
#synthesize name;
#synthesize year;
#synthesize length;
#synthesize file_size;
#synthesize rating;
#synthesize genre;
#synthesize plot;
-(id)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot{
self.name = newName;
self.year = newYear;
self.length = newLength;
self.file_size = newFileSize;
self.rating = newRating;
self.genre = newGenre;
self.plot = newPlot;
return self;
}
- (void)encodeWithCoder:(NSCoder *)encode;
{
[encode encodeObject:name forKey:#"name"];
[encode encodeInt32:year forKey:#"year"];
[encode encodeInt32:length forKey:#"length"];
[encode encodeObject:file_size forKey:#"file_size"];
[encode encodeInt32:rating forKey:#"rating"];
[encode encodeObject:genre forKey:#"genre"];
[encode encodeObject:plot forKey:#"plot"];
}
- (id)initWithCoder:(NSCoder *)decode;
{
NSString *name_decode = [decode decodeObjectForKey:#"name"];
int year_decode = [decode decodeInt32ForKey:#"year"];
int length_decode = [decode decodeInt32ForKey:#"length"];
NSString *file_size_decode = [decode decodeObjectForKey:#"file_size"];
int rating_decode = [decode decodeInt32ForKey:#"rating"];
NSArray *genre_decode = [decode decodeObjectForKey:#"genre"];
NSString *plot_decode =[decode decodeObjectForKey:#"plot"];
return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
}
#end
Save Action (Movies is the NSMutableArray containing my Objects):
NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:Movies];
[userDefault setObject:encodedData forKey:[NSString stringWithFormat:#"MOVIES"]];
Load Action:
NSData *decodedData = [userDefault objectForKey: [NSString stringWithFormat:#"MOVIES"]];
NSArray *decodedArray =[NSKeyedUnarchiver unarchiveObjectWithData: decodedData];
The returned Array is always (null)... i have no clue
I tried several different kind of code snippets i found on the internet and/or stackoverflow
Your Movie initWithName... method is incorrect. It needs to be:
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
self = [super init];
if (self) {
self.name = newName;
self.year = newYear;
self.length = newLength;
self.file_size = newFileSize;
self.rating = newRating;
self.genre = newGenre;
self.plot = newPlot;
}
return self;
}
Also, you seem to be following a very out-of-date tutorial.
You don't need to declare the ivars for your properties.
You don't need the calls to #synthesize.
You should be using ARC instead of MRC, Therefore your retain properties should be strong (thought the NSString properties should be copy.
Your init methods should return instancetype, not id.
With all of that in mind, your Movie class should be as follows:
Movie.h
#interface Movie : NSObject <NSCoding>
#property (nonatomic, copy) NSString *name;
#property (nonatomic, assign) int year;
#property (nonatomic, assign) int length;
#property (nonatomic, copy) NSString *file_size;
#property (nonatomic, assign) int rating;
#property (nonatomic, strong) NSArray *genre;
#property (nonatomic, copy) NSString *plot;
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot;
#end
Movie.m
#implementation Movie
- (instancetype)initWithName:(NSString *)newName year:(int)newYear length:(int)newLength filesize:(NSString *)newFileSize rating:(int)newRating genre:(NSArray *)newGenre plot:(NSString *)newPlot {
self = [super init];
if (self) {
_name = newName;
_year = newYear;
_length = newLength;
_file_size = newFileSize;
_rating = newRating;
_genre = newGenre;
_plot = newPlot;
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)encode;
{
[encode encodeObject:self.name forKey:#"name"];
[encode encodeInt32:self.year forKey:#"year"];
[encode encodeInt32:self.length forKey:#"length"];
[encode encodeObject:self.file_size forKey:#"file_size"];
[encode encodeInt32:self.rating forKey:#"rating"];
[encode encodeObject:self.genre forKey:#"genre"];
[encode encodeObject:self.plot forKey:#"plot"];
}
- (instancetype)initWithCoder:(NSCoder *)decode;
{
NSString *name_decode = [decode decodeObjectForKey:#"name"];
int year_decode = [decode decodeInt32ForKey:#"year"];
int length_decode = [decode decodeInt32ForKey:#"length"];
NSString *file_size_decode = [decode decodeObjectForKey:#"file_size"];
int rating_decode = [decode decodeInt32ForKey:#"rating"];
NSArray *genre_decode = [decode decodeObjectForKey:#"genre"];
NSString *plot_decode =[decode decodeObjectForKey:#"plot"];
return [self initWithName:name_decode year:year_decode length:length_decode filesize:file_size_decode rating:rating_decode genre:genre_decode plot:plot_decode];
}
#end
You don't show how you create and populate your Movies variable (which should be named movies, not Movies. Make sure it isn't nil.
Also, don't needlessly use stringWithFormat.
Your saving code should be:
NSUserDefaults *userDefault=[NSUserDefaults standardUserDefaults];
NSData *encodedData = [NSKeyedArchiver archivedDataWithRootObject:movies];
[userDefault setObject:encodedData forKey:#"MOVIES"];
and your loading code should be:
NSData *decodedData = [userDefault objectForKey:#"MOVIES"];
NSArray *decodedArray = [NSKeyedUnarchiver unarchiveObjectWithData: decodedData];
A quick test is to see if the mutable array is actually not nil itself. Try outputting the mutable array before setting it in userDefaults.
Make sure the mutable array is initialized before trying to add objects to it.
movies = [[NSMutableArray alloc] init];
I have a NSMutableaArray of NSString objects. So i'm using NSKeyedArchiever to save it to disk. So when i try to use
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:self.EventsList forKey:#"Events"];
}
i got an error
Event encodeWithCoder:]: unrecognized selector sent to instance 0x7fd06b542780
Here's my parts of code:
//-------------------Events.h--------------------------
#interface Event : NSObject
#property (strong,nonatomic) NSString *nameOfEvent;
#property (strong,nonatomic) NSString *dateOfEvent;
#property (strong,nonatomic) NSString *placeOfEvent;
#property int priorityOfEvent;
#end
//---------------Singleton.h ----------------
#interface GlobalSingleton : NSObject <NSCoding, NSCopying> {
NSMutableArray *EventsList;
}
#property (nonatomic,retain) NSMutableArray *EventsList;
+(GlobalSingleton *)sharedFavoritesSingleton;
#end
//----------------Singleton.m------------------------
....
#implementation GlobalSingleton
#synthesize EventsList;
....
....
- (void)encodeWithCoder:(NSCoder *)aCoder {
NSLog (#"%#",EventsList); // not nil
[aCoder encodeObject:self.EventsList forKey:#"Events"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
if ((self = [super init])) {
NSMutableArray *temp = [[NSMutableArray alloc] initWithArray:[aDecoder decodeObjectForKey:#"Events"]];
self.EventsList = temp;
}
return self;
}
- (id)copyWithZone:(NSZone *)zone {
GlobalSingleton *copy = [[GlobalSingleton allocWithZone:zone] init];
copy.EventsList = self.EventsList;
return copy;
}
#end
I get textdata from Web-server using ASIFormDataRequest in JSON format, and then i add this object to NSMutableArray, which is also a Singleton, so it looks like this:
NSDictionary *responseDict = [responseString JSONValue];
GlobalSingleton *Singleton = [GlobalSingleton sharedFavoritesSingleton];
for (NSDictionary *str in responseDict) {
Event *newEvent = [[Event alloc] init];
newEvent.nameOfEvent = [str objectForKey:#"EventName"];
newEvent.dateOfEvent = [str objectForKey:#"EventDate"];
newEvent.placeOfEvent = [str objectForKey:#"EventPlace"];
[Singleton.EventsList addObject:newEvent];
}
//------------------Save this data stored in NSMutableArray to disk-------------------------
[NSKeyedArchiver archiveRootObject:Singleton toFile:[self save_path]];
So, again, execution stops on this:
[aCoder encodeObject:self.EventsList forKey:#"Events"];
But when i try to code single NSString object everything goes with no errors.
eventList doesn't contain NSStrings, it contains Event objects.
Your Event class needs to implement encodeWithCoder: - as the exception message says, the Event class doesn't implement this method.
Also you should use a lowercase s for singleton as it is an instance, not a class, and you should probably not use singletons.
This question already has answers here:
How to store custom objects in NSUserDefaults
(7 answers)
Closed 9 years ago.
I am trying to save an NSDictionary to my NSUserDefualts.
The dictionary consists of 3 different custom classes.
#interface PastOrder : NSObject <NSCoding>
{
NSDate *timeIn;
NSDate *timeOut;
NSString *status;
NSMutableArray *myItems;
}
#property (nonatomic, retain) NSDate *timeIn;
#property (nonatomic, retain) NSDate *timeOut;
#property (nonatomic, retain) NSString *status;
#property (nonatomic, retain) NSMutableArray *myItems;
#end
#implementation PastOrder
#synthesize timeIn, timeOut, status, myItems;
#define PastOrderTimeInKey #"PastOrderTimeInKey"
#define PastOrderTimeOutKey #"PastOrderTimeOutKey"
#define PastOrderStatusKey #"PastOrderStatusKey"
#define PastOrderMyItemsKey #"PastOrderMyItemsKey"
-(id)initWithCoder:(NSCoder*)decoder
{
self = [super init];
if(self)
{
self.timeIn = [decoder decodeObjectForKey:PastOrderTimeInKey];
self.timeOut = [decoder decodeObjectForKey:PastOrderTimeOutKey];
self.status = [decoder decodeObjectForKey:PastOrderStatusKey];
self.myItems = [decoder decodeObjectForKey:PastOrderMyItemsKey];
}
return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder
{
[encoder encodeObject:self.timeIn forKey:PastOrderTimeInKey];
[encoder encodeObject:self.timeOut forKey:PastOrderTimeOutKey];
[encoder encodeObject:self.status forKey:PastOrderStatusKey];
[encoder encodeObject:self.myItems forKey:PastOrderMyItemsKey];
}
-(void)dealloc
{
self.timeIn = nil;
self.timeOut = nil;
self.status = nil;
self.myItems = nil;
}
#end
#interface PastOrderItem : NSObject <NSCoding>
{
NSNumber *itemID;
NSString *status;
NSMutableArray *itemChoices;
}
#property (nonatomic, retain) NSNumber *itemID;
#property (nonatomic, retain) NSString *status;
#property (nonatomic, retain) NSMutableArray *itemChoices;
#end
#implementation PastOrderItem
#synthesize itemID,status,itemChoices;
#define PastOrderItemItemIDKey #"PastOrderItemItemIDKey"
#define PastOrderItemStatusKey #"PastOrderItemStatusKey"
#define PastOrderItemItemChoicesKey #"PastOrderItemItemChoicesKey"
-(id)initWithCoder:(NSCoder*)decoder
{
self = [super init];
if(self)
{
self.itemID = [decoder decodeObjectForKey:PastOrderItemItemIDKey];
self.itemChoices = [decoder decodeObjectForKey:PastOrderItemItemChoicesKey];
self.status = [decoder decodeObjectForKey:PastOrderItemStatusKey];
}
return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder
{
[encoder encodeObject:self.itemID forKey:PastOrderItemItemIDKey];
[encoder encodeObject:self.itemChoices forKey:PastOrderItemItemChoicesKey];
[encoder encodeObject:self.status forKey:PastOrderItemStatusKey];
}
-(void)dealloc
{
self.itemID = nil;
self.itemChoices = nil;
self.status = nil;
}
#end
#interface PastOrderItemChoice : NSObject <NSCoding>
{
NSNumber *modifierID;
NSNumber *modifierChoice;
}
#property (nonatomic, retain) NSNumber *modifierID;
#property (nonatomic, retain) NSNumber *modifierChoice;
#end
#implementation PastOrderItemChoice
#synthesize modifierID, modifierChoice;
#define PastOrderItemChoiceModifierIDKey #"PastOrderItemChoiceModifierIDKey"
#define PastOrderItemChoiceModifierChoiceKey #"PastOrderItemChoiceModifierChoiceKey"
-(id)initWithCoder:(NSCoder*)decoder
{
self = [super init];
if(self)
{
self.modifierID = [decoder decodeObjectForKey:PastOrderItemChoiceModifierIDKey];
self.modifierChoice = [decoder decodeObjectForKey:PastOrderItemChoiceModifierChoiceKey];
}
return self;
}
-(void)encodeWithCoder:(NSCoder*)encoder
{
[encoder encodeObject:self.modifierID forKey:PastOrderItemChoiceModifierIDKey];
[encoder encodeObject:self.modifierChoice forKey:PastOrderItemChoiceModifierChoiceKey];
}
-(void)dealloc
{
self.modifierID = nil;
self.modifierChoice = nil;
}
#end
Those are the three classes that will be inside this NSDictionary.
Here is how I Load and Save it.
-(void)SavePrefs
{
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSData* data=[NSKeyedArchiver archivedDataWithRootObject:self.myDictionary];
[prefs setObject:data forKey:#"SavedOrders"];
[prefs synchronize];
}
- (id)init
{
self = [super init];
if (self)
{
NSData* data = [[NSUserDefaults standardUserDefaults] objectForKey:#"SavedOrders"];
self.myDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:data];
}
return self;
}
I have experimented with the code a bit, and best I have to far, is that when I save the dictionary, it was 135 bytes, same as when I loaded it, but it still didnt fill the dictionary up. So I am at a loss.
Your code seems to be good. I can't find a mistake so try to change line:
self.myDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:data];
to
id unknownObject = [NSKeyedUnarchiver unarchiveObjectWithData:data];
NSLog(#"%#",[unknownObject class]);
And look # the console. Maybe you should also try casting if the output will be dictionary. So try to change this to:
self.myDictionary = (NSDictionary*)[NSKeyedUnarchiver unarchiveObjectWithData:data];
EDIT
NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:#"object1",#"key1",#"object2",#"key2",#"object3",#"key3", nil];
NSLog(#"before: %#",dictionary);
NSData *myData = [NSKeyedArchiver archivedDataWithRootObject:dictionary];
NSDictionary *myDictionary = (NSDictionary*) [NSKeyedUnarchiver unarchiveObjectWithData:myData];
NSLog(#"after: %#",myDictionary);
Output:
2013-11-13 14:32:31.369 DemoM[175:60b] before: {
key1 = object1;
key2 = object2;
key3 = object3;
}
2013-11-13 14:32:31.372 DemoM[175:60b] after: {
key1 = object1;
key2 = object2;
key3 = object3;
}
I am using an NSData to store an object for later use. It has quite a few NSStrings and I need to pull it out of an object.
For some reason, only some of the NSStrings are stored and some others get zeroed out!
I was thinking it must be something with my code, that I must have forgotten to initialize some string, but for a very weird reason some of the strings lose the data!
I can't get theImportantString to get it's relevant value because it first seems like the variable got it's value, but after coming back from Unarchive, it's equal to #""!
// CMyData.h
/////////////////////
#interface CMyData : NSObject <NSCoding>
{
NSString *ID;
NSString *DIST;
.
.
}
#property (nonatomic,retain) NSString *ID;
#property (nonatomic,retain) NSString *DIST;
#end
// CMyData.m
//////////////////////
#import "CMyData.h"
#implementation CMyData
#synthesize ID;
#synthesize DIST;
- (id)initWithCoder:(NSCoder *)decoder {
if (self = [super init]) {
self.ID = [decoder decodeObjectForKey:#"ID"];
self.DIST = [decoder decodeObjectForKey:#"DIST"];
.
.
}
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:ID forKey:#"ID"];
[encoder encodeObject:DIST forKey:#"DIST"];
.
.
}
- (void)dealloc {
[ID release];
[DIST release];
[super dealloc];
}
#end
MyController.m
-(void) makeObject: (NSDictionary *)dict
{
CMyData* myData=[[CMyData alloc] init];
myData.ID = [[NSString alloc] initWithString:[dict objectForKey:#"NAME"]];
myData.DIST = [[NSString alloc] initWithString:[dict objectForKey:#"DISTRIBUTOR"]];
.
.
myObject = [[[MYObject alloc] init];
myObject.data = [NSKeyedArchiver archivedDataWithRootObject:myData];
}
And then a tap on a button happens:
- (void) tapOnIcon: (MyObject*)theObject
{
CMyData *data = [NSKeyedUnarchiver unarchiveObjectWithData:theObject.data];
[delegate showData:data];
}
in the delegate Controller (Where the value can't be set anymore):
delegateController.m
/////////////////////////////////
-(void) showData:(CMyData*)theData{
self.theImportantString = [[NSString alloc] initWithString:theData.DIST];
.
.
.
}
Seems you have types mismatch:
// in - (id)initWithCoder:(NSCoder *)decoder
self.DIST = [decoder decodeIntForKey:#"DIST"];
but in declaration you have
// in CMyData.h
NSString *DIST;
This should be:
// in - (id)initWithCoder:(NSCoder *)decoder
self.DIST = [NSString stringWithFormat:#"%d", [decoder decodeIntForKey:#"DIST"]];