Change or Update NSMuttableDictionary - ios

How to Change or Update NSMuttableDictionary i apply code below
in User.h file the code
#interface User : NSObject
#property (nonatomic, strong) NSNumber *userID;
#property (nonatomic, strong) NSString *avatar;
#property (nonatomic, strong) NSString *firstname;
-(User *)initWithDictionary:(NSDictionary *)dictionary;
#end
then in User.m file the code
#import "User.h"
#implementation User
#synthesize userID;
#synthesize avatar;
#synthesize firstname;
-(User *)initWithDictionary:(NSDictionary *)dictionary
{
self = [super init];
if (self)
{
self.userID = [dictionary objectForKey:#"IdUser"];
self.avatar = [dictionary objectForKey:#"Avatar"];
self.firstname = [dictionary objectForKey:#"FirstName"];
}
return self;
}
#end
in my .pch file
#define AppDelegateInstance ((AppDelegate *)[UIApplication sharedApplication].delegate)
then i got the all key and value like this
AppDelegateInstance.loggedUser = [[User alloc] initWithDictionary:[tempArray objectAtIndex:0]];
Response == (
{
IdUser = 1;
Avatar = "Nishant_1.jpg
FirstName = Nishant;
}
)
Now my question is How to update
{
Avatar = "Nishant_1.jpg(Not update **Nishant_1.jpg** to **xyz.jpg**)
FirstName = Nishant(Not Update **Nishant** to **xyz**);
}
If anybody know this plz give me some answer to solve my query
Thanks in Advanced!!!

- (void)updateWithDictionary:(NSDictionary *)dictionary
{
id userId = [dictionary objectForKey:#"IdUser"] ;
if (userId) {
self.userID = userId ;
}
id avatar = [dictionary objectForKey:#"Avatar"] ;
if (avatar) {
self.avatar = avatar ;
}
id firstname = [dictionary objectForKey:#"FirstName"];
if (firstname) {
self.firstname = firstname ;
}
}

Why don't you write a method to update your properties like
-(User *)updateWithDictionary:(NSDictionary *)dictionary
{
if (self)
{
self.userID = [dictionary objectForKey:#"IdUser"];
self.avatar = [dictionary objectForKey:#"Avatar"];
self.firstname = [dictionary objectForKey:#"FirstName"];
}

Related

NSUserdefaults not working with NSKeyedArchiver

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];

Parse JSON to a tree structure

I'm working on a project that requires a tableView list of categorized grocery items. Each category can have n depth. The JSON response from the API looks like this.
"items":[
{
"id":"5366f8d3e4b0e44dc2d4a6fb",
"name":"String Cheese"
"description":"Sargento String Cheese",
"categorization":[
[
"Dairy",
"Cheese"
]
]
},
{
"id":"5366f8d3e4b0e44dc2d1a6fb",
"name":"Budlight 6-pk"
"description":"Budlight 12-pk",
"categorization":[
[
"Beverages",
"Alcohol",
"Beer"
]
]
}
]
Right now I'm creating Item objects from the item dictionaries and storing them in a mutable array like below.
NSArray *itemsArray = [response objectForKey:items];
NSMutableArray *itemsMutableArray = [[NSMutableArray alloc] init];
for(NSDictionary *itemDict in itemsArray){
Item *itemObj = [[Item alloc] initWithDictionary:itemDict]
[itemsMutableArray addObject:itemObj];
}
I would like to loop through itemsMutableArray and create a tree data structure that has a path from the root to each of the items. Then, I would like to be able to use the tree as a datasource for tableViews in each level of category.
Here's what my Item class header looks like.
#interface Item : NSObject
#property (nonatomic, strong) NSString *id;
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *description;
#property (nonatomic, strong) NSArray *categorization;
#end
...and the implementation
#import "Item.h"
#implementation Item
- (id)initWithDictionary:(NSDictionary *)objDictionary{
if (self = [super init]) {
self.id = [objDictionary valueForKey:#"id"];
self.name = [objDictionary valueForKey:#"name"];
self.description = [objDictionary valueForKey:#"description"];
self.categorization = [objDictionary valueForKey:#"categorization"];
}
return self;
}
#end
I am not very familiar with tree data structures and recursion. I would greatly appreciate any help on how to approach this. Thanks!
If you need simple node tree data structure. How about this way?
Hope this little help.
Header
#interface ItemCategory : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic) ItemCategory *parent;
#property (nonatomic, strong) NSMutableArray *children;
-(id)initWithName:(NSString *)n parent:(ItemCategory *)p;
#end
#interface CategoryTree : NSObject
#property (nonatomic, strong) ItemCategory *root;
-(ItemCategory *)_getChildCategory:(ItemCategory *)category name:(NSString *)name;
-(ItemCategory *)_addChildCategory:(ItemCategory *)category name:(NSString *)name;
-(void)_dumpCategory:(ItemCategory *)category depth:(int)depth;
-(void)dump;
-(ItemCategory *)getCategory:(NSArray *)arr;
-(void)addCategory:(NSArray *)arr;
#end
Source
#implementation CategoryTree
#synthesize root;
-(id)init {
if (self = [super init]) {
root = [[ItemCategory alloc] initWithName:#"root" parent:nil];
}
return self;
}
-(ItemCategory *)_getChildCategory:(ItemCategory *)category name:(NSString *)name {
for (ItemCategory *child in category.children)
if ([child.name isEqualToString:name])
return child;
return nil;
}
-(ItemCategory *)_addChildCategory:(ItemCategory *)category name:(NSString *)name {
ItemCategory *child = [self _getChildCategory:category name:name];
if (child)
return child;
child = [[ItemCategory alloc] initWithName:name parent:category];
[category.children addObject:child];
return child;
}
-(void)_dumpCategory:(ItemCategory *)category depth:(int)depth{
NSString *parentStr = #"";
ItemCategory *parent = category.parent;
while (parent) {
parentStr = [NSString stringWithFormat:#"%#%#%#", parent.name, parentStr.length > 0 ? #">" : #"", parentStr];
parent = parent.parent;
}
NSLog(#"%#%#%#", parentStr, parentStr.length > 0 ? #">" : #"", category.name);
for (ItemCategory *child in category.children) {
[self _dumpCategory:child depth:depth + 1];
}
}
-(void)dump {
[self _dumpCategory:root depth:0];
}
-(ItemCategory *)getCategory:(NSArray *)arr {
ItemCategory *category = root;
for (NSString *categoryName in arr) {
category = [self _getChildCategory:category name:categoryName];
if (!category)
return nil;
}
return category;
}
-(void)addCategory:(NSArray *)arr {
if ([self getCategory:arr])
return;
ItemCategory *category = root;
for (NSString *categoryName in arr) {
ItemCategory *childCategory = [self _getChildCategory:category name:categoryName];
if (!childCategory) {
childCategory = [self _addChildCategory:category name:categoryName];
}
category = childCategory;
}
}
#end
Usage
CategoryTree *tree = [[CategoryTree alloc] init];
[tree addCategory:#[#"Dairy", #"Cheese"]];
[tree addCategory:#[#"Dairy", #"Milk"]];
[tree addCategory:#[#"Beverages", #"Alcohol", #"Beer"]];
[tree addCategory:#[#"Beverages", #"Alcohol", #"Wine"]];
[tree addCategory:#[#"Beverages", #"Non-Alcohol", #"Cola"]];
[tree dump];
Result
root
root>Dairy
root>Dairy>Cheese
root>Dairy>Milk
root>Beverages
root>Beverages>Alcohol
root>Beverages>Alcohol>Beer
root>Beverages>Alcohol>Wine
root>Beverages>Non-Alcohol
root>Beverages>Non-Alcohol>Cola
well I have found a way to implement what you need. I do not know how optimised it is since i do not how many items you'll be receiving . The implementation is given below.
You need to start with adding this dictionary in Item.h #property (nonatomic, strong) NSMutableDictionary *catTree;
Next do this to get the tree
[itemsMutableArray enumerateObjectsUsingBlock:^(Item *itm, NSUInteger i,BOOL *stop){
itm.catTree = [NSMutableDictionary dictionary];
NSString *dairy = #"",*beverage = #"";
for (NSArray *catArray in itm.categorization) {
/*
Everything below is written assuming the format of the JSON will be "as-is"
*/
if ([catArray containsObject:#"Dairy"]) {
//Take everything except Dairy
NSArray *stripedArray = [catArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != \"Dairy\""]];
int i = 0;
//Loop through the array to get any sub categories.
while (i < stripedArray.count) {
dairy = [dairy stringByAppendingString:[NSString stringWithFormat:(i == stripedArray.count-1)?#"%# ":#"%#->",stripedArray[i]]]; //Space at the end to account for similar entry in the same category for e.g two dairy products.
i++;
}
} else if ([catArray containsObject:#"Beverages"]) {
NSArray *stripedArray = [catArray filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"SELF != \"Beverages\""]];
int i = 0;
while (i < stripedArray.count) {
beverage = [beverage stringByAppendingString:[NSString stringWithFormat:(i == stripedArray.count-1)?#"%# ":#"%#->",stripedArray[i]]];
i++;
}
}
}
//Set the category tree for every item using a dictionary
[itm.catTree setValue:dairy forKey:#"Dairy"];
[itm.catTree setValue:beverage forKey:#"Beverage"];
NSLog(#"%#",itm.catTree);
}];
the above code gives the following output for your json
{
Beverage = "";
Dairy = "Cheese ";
}
{
Beverage = "Alcohol->Beer ";
Dairy = "";
}
For multiple beverages
{
Beverage = "Alcohol->Beer Alcohol->Wine->Red Soda->Coke ";
Dairy = "";
}
Hope this helps.

iOS: Singleton returning null

I have a singleton and I pass data to it but it returns null can you please help me in my situation. Thanks in advance :)
Here's my code
Card.h
#property (weak,nonatomic) NSString *email;
#property (weak,nonatomic) NSString *fName;
#property (weak,nonatomic) NSString *lName;
#property (weak,nonatomic) NSString *category;
+(Card *)getCard;
Card.m
#synthesize email;
#synthesize fName;
#synthesize lName;
#synthesize category;
static csCard *instance;
+(Card *) getCard
{
#synchronized (self)
{
if(instance == nil)
{
instance = [[Card alloc]init];
}
}
return instance;
}
- (id) init{
self.email = [[NSUserDefaults standardUserDefaults]stringForKey:#"email"];
self.fName = [[NSUserDefaults standardUserDefaults]stringForKey:#"firstName"];
self.lName = [[NSUserDefaults standardUserDefaults]stringForKey:#"lastName"];
self.category = #"TestCategory";
return self;
}
and here's my test code to see if it's working
Test.m
Card *card = [Card getCard];
[card setEmail:self.emailField.text];
NSLog(#"%#",card.email);
but this code give me (null)
Modify your class like this.
Card.h
#property (strong,nonatomic) NSString *email; //Let the modal be strong property
#property (strong,nonatomic) NSString *fName;
#property (strong,nonatomic) NSString *lName;
#property (strong,nonatomic) NSString *category;
+(Card *)getCard;
Card.m
static Card *instance;
+(Card *) getCard
{
#synchronized (self)
{
if(instance == nil)
{
instance = [[Card alloc]init];
}
}
return instance;
}
- (NSString)email{
return [[NSUserDefaults standardUserDefaults]stringForKey:#"email"];
}
- (void)setEmail:(NSString)email{
[[NSUserDefaults standardUserDefaults] setString:email forkey:#"email"];
}
No need of overriding init
in your test class
Card *card = [Card getCard];
[card setEmail:self.emailField.text];
NSLog(#"%#",card.email);
static csCard *instance;
+(csCard *) getCard
{
#synchronized (self)
{
if(instance == nil)
{
instance = [[csCard alloc]init];
}
}
return instance;
}
Replace it with this code
static Card *instance;
+(Card *) getCard
{
#synchronized (self)
{
if(instance == nil)
{
instance = [[Card alloc]init];
}
}
return instance;
}
The Class name Of the instance Object was wrong and In singleton method,the return datatype was also wrong. I think u will understand what I am saying.
+ (Card *)instance {
static Card *sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedInstance = [[Card alloc] init];
});
return sharedInstance;
}
It should be work
With the help of what βhargavḯ sujjested u can modify your code as below because
in the line static csCard *instance; u are using csCard i think it is typo so better u can do like this,
#import "Card.h"
static dispatch_once_t onceDispach;
#implementation Card
#synthesize email = _email;
#synthesize fName;
#synthesize lName;
#synthesize category;
static Card *instance = nil; //change this to Card because this instance which is of type Card
+(Card *)getCard
{
dispatch_once(&onceDispach, ^{
instance = [[self alloc] init];//careate Card shared object named instance
});
return instance;
}
- (id) init
{
self.email = [[NSUserDefaults standardUserDefaults]stringForKey:#"email"];
self.fName = [[NSUserDefaults standardUserDefaults]stringForKey:#"firstName"];
self.lName = [[NSUserDefaults standardUserDefaults]stringForKey:#"lastName"];
self.category = #"TestCategory";
return self;
}
#end
- (NSString *)email
{
return _email;
}
- (void)setEmail:(NSString *)email
{
_email = email;
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
[userDefault setObject:email forKey:#"email"];
}
in the class where u are using this shared instance use like below
- (void)actionMathodCalled
{
Card *card = [Card getCard];
NSLog(#"before saving to defaults->%#",card.email);
[card setEmail:#"happyCoding#ymail.com"];
NSLog(#"after savng to defaults->%#",card.email);
}

Saving NSDictionary (with custom classes) to NSUserDefaults [duplicate]

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;
}

NSObject custom init with object/parameters

What i'm trying to accomplish is something like
Person *person1 = [[Person alloc]initWithDict:dict];
and then in the NSObject "Person", have something like:
-(void)initWithDict:(NSDictionary*)dict{
self.name = [dict objectForKey:#"Name"];
self.age = [dict objectForKey:#"Age"];
return (Person with name and age);
}
which then allows me to keep using the person object with those params. Is this possible, or do I have to do the normal
Person *person1 = [[Person alloc]init];
person1.name = #"Bob";
person1.age = #"123";
?
Your return type is void while it should instancetype.
And you can use both type of code which you want....
Update:
#interface testobj : NSObject
#property (nonatomic,strong) NSDictionary *data;
-(instancetype)initWithDict:(NSDictionary *)dict;
#end
.m
#implementation testobj
#synthesize data;
-(instancetype)initWithDict:(NSDictionary *)dict{
self = [super init];
if(self)
{
self.data = dict;
}
return self;
}
#end
Use it as below:
testobj *tt = [[testobj alloc] initWithDict:#{ #"key": #"value" }];
NSLog(#"%#",tt.ss);
change your code like this
-(id)initWithDict:(NSDictionary*)dict
{
self = [super init];
if(self)
{
self.name = [dict objectForKey:#"Name"];
self.age = [dict objectForKey:#"Age"];
}
return self;
}
So you can use modern objective-c style to get associative array values ;)
-(id)initWithDict:(NSDictionary*)dict
{
self = [super init];
if(self)
{
self.name = dict[#"Name"];
self.age = dict[#"Age"];
}
return self;
}

Resources