Saving NSDictionary with NSMutableArray as a value to NSUserDefaults - iphone

I am storing UIImage in NSMutableArray then storing NSMutableArray into NSDictionary.
Key of NSDictionary is a foldername and value of NSDictionary is a NSMutableArray.
Now how can i store and retrieve NSDictionary in NSUserDefaults.
I have done as follows:
NSMutableArray *imageArray=[[NSMutableArray alloc] init];
[imageArray addObject:selectedImage];
[allFolderWithImageDict setValue:imageArray forKey:#"UniqueFolderName"];
NSUserDefaults *defauktCenter = [NSUserDefaults standardUserDefaults];
[defauktCenter setValue:allFolderWithImageDict forKey:#"FolderImageDict"];
[defauktCenter synchronize];
But NSDictionary is not saving in NSUserDefaults.
Please suggest with some example
thanks

To Store and Retrieve Values of Custom Objects, you can use NSKeyedArchiver and NSKeyedUnarchiver Classes :
// To Save. . .
NSData *resData = [NSKeyedArchiver archivedDataWithRootObject:allFolderWithImageDict];
[[NSUserDefaults standardUserDefaults] setObject:resData forKey:#"FolderImageDict"];
// To Load. . .
NSData *respData = [[NSUserDefaults standardUserDefaults] objectForKey:#"FolderImageDict"];
resultDictionary = [NSKeyedUnarchiver unarchiveObjectWithData:respData];
NSLog(#"dict :: %#",resultDictionary);
GoodLuck !!!

To store UIImage objects in NSUserDefaults you need to a category implementation for UIImage that implements NSCoding protocol
here is one:
https://code.google.com/p/iphonebits/source/browse/trunk/src/Categories/UIImage-NSCoding.h
https://code.google.com/p/iphonebits/source/browse/trunk/src/Categories/UIImage-NSCoding.m
from
http://iphonedevelopment.blogspot.it/2009/03/uiimage-and-nscoding.html

Instead of using NSDictionary, use NSMutableDictionary.... :)
And to retrieve the data stored in dictionary.....
NSUserDefaults *d = [NSUserDefaults standardUserDefaults];
NSString *loadname1 = [d objectForKey:#"FolderImageDict"];
NSLog(#"%#", loadname1);

Related

Why can I return a NSMutableArray from NSUserDefaults but not an NSMutableDictionary

I'm saving several items in NSUserDefaults in iOS 6. In the past I have always used an NSMutableArray that contains NSMutableDictionaries to save some info. But now I've decided it would be more efficient to use an NSMutableDictionary that contains NSMutableDictionaries. I want to be able to delete dictionaries from the main NSMutableDictionary and modify the values stored in the subdictionaries.
I've been storing my main NSMutableArray as:
-(NSMutableArray *)listArray
{
return [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"list_array"];
}
-(void) setDeviceListArray:(NSMutableArray *)listArray
{
[[NSUserDefaults standardUserDefaults] setObject:listArray forKey:#"list_array"];
}
I would do the same for NSMutableDictionary but there is no getter function like 'mutableDictionaryValueForKey' that exists. Can someone tell me why this is??
just because :D
copy the dictionary like this
NSMutableDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryForKey:#"bla"].mutableCopy;

Array within a NSDictionary: how to save to the NSUserDefaults

I would like to save Array/NSDictionary to NSUserDefaults but anything I try is just not working. Here is my code so please if you know how to do this, help me.
NSArray *oneArray = [NSArray arrayWithObjects:#"Radio One",nil];
NSDictionary *one = [NSDictionary dictionaryWithObject:oneArray forKey:#"Stations"];
NSArray *oneLinkArray = [NSArray arrayWithObjects:#"http://mobile.com:28000/",nil];
NSDictionary *oneLink = [NSDictionary dictionaryWithObject:oneLinkArray forKey:#"Stations"];
[data addObject:one];
[link addObject:oneLink];
The reason I need this is to put this station into favorites. So my thinking is to save these info in to NSUserDefaults and retrieve in favorites table.
Thanks and please any suggestion is welcomed and appreciated.
You can use something like this when you store everything into a dictionary
[[NSUserDefaults standardUserDefaults] setObject:link forKey:#"dictionary1"];
Or you can put everything into an array and store it like this
[[NSUserDefaults standardUserDefaults] setObject:data forKey:#"array1"];
You can access it again by using
NSDictionary * myDictionary = [[NSUserDefaults standardUserDefaults] dictionaryForKey:#"dictionary1"];
Typically adding an object into NSUserDefaults goes like this:
NSMutableDictionary *dictionaryToAdd = [[NSMutableDictionary alloc] init];
[dictionaryToAdd setObject:#"xyz" forKey:#"myKey"];
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[myDefaults setObject:dictionaryToAdd forKey:#"someKey"];
[myDefaults synchronize];
A few things on your code above though - you're adding stuff into 'data' and 'link' but I don't see those in your code, so I'm assuming those arrays exist somewhere.
To sum it up - declare an NSUserDefaults object, set objects into it like an NSDictionary, and then synchronize it to save data.
Additional code as requested:
//You have an array named arrayToAdd that has already been created
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
[myDefaults setObject:arrayToAdd forKey:#"SomeKeyThatYouMakeUp"];
[myDefaults synchronize];
//You want to get the array out of NSUserDefaults
NSArray *mySavedArray;
NSUserDefaults *myDefaults = [NSUserDefaults standardUserDefaults];
mySavedArray = [myDefaults objectForKey:#"SomeKeyThatYouMakeUp"];

Saving ALAsset URL in NSUserDefaults

Hi I have my ALAsset URL save in NSMutableArray,
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=119A0D2D-C267-4B69-A200-59890B2B0FE5&ex‌​t=JPG",
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=92A7A24F-D54B-496E-B250-542BBE37BE8C&ex‌​t=JPG",
"ALAsset - Type:Photo, URLs:assets-library://asset/asset.JPG?id=77AC7205-68E6-4062-B80C-FC288DF96F24&ex‌​t=JPG
I wasnt able to save NSMutableArray in NSUserDefaults due to it having an error Note that dictionaries and arrays in property lists must also contain only property values.
Im thinking of using this :
- (void)encodeWithCoder:(NSCoder *)encoder {
//Encode properties, other class variables, etc
[encoder encodeObject:self.selectedPhotos forKey:#"selectedPhotos"];
}
- (id)initWithCoder:(NSCoder *)decoder {
if((self = [super init])) {
//decode properties, other class vars
self.selectedPhotos = [decoder decodeObjectForKey:#"selectedPhotos"];
}
return self;
}
then save and retrieve it with this code:
- (void)saveCustomObject:(MyCustomObject *)obj {
NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myEncodedObject forKey:#"myEncodedObjectKey"];
}
- (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *myEncodedObject = [defaults objectForKey:key];
MyCustomObject *obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
return obj;
}
But I somehow dont quite get it, still crashes in my code. Dont know how. And I wasnt able to save it in NSUserDefaults. Hope someone help. Really been having problem with this a while. Hope someone guide me on the right path of saving and retrieving it the right way from NSUserDefaults. Then back to a NSMutableArray.
The NSUserDefaults only takes a restricted set of classes as objects. See the documentation. You must take care only to store values of these types (NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary, and of course it applies recursively) in the dictionary.
To store the URLs in the NSUserDefaults, store them as strings, then read them back as URLs. If you need to have the dictionary in the current format, you may have to transform it before saving it.
- (void) saveMyUrls
{
NSMutableArray* urls = [NSMutableArray arrayWithCapacity:self.myUrls.count];
for(NSURL* url in self.myUrls) {
[urls addObject:[url absoluteString]];
}
[[NSUserDefaults standardUserDefaults] setObject:urls forKey:#"myUrls"];
}
- (void) loadUrls
{
NSArray* urls = [[NSUserDefaults standardUserDefaults] objectForKey:#"myUrls"];
self.myUrls = [NSMutableArray arrayWithCapacity:urls.count];
for(NSString* urlString in urls) {
[self.myUrls addObject:[NSURL URLWithString:urlString]];
}
[[NSUserDefaults standardUserDefaults] setObject:urls forKey:#"myUrls"];
}
If you need to save more information than just the URL, let's say a user-specified label, you could save the object as a NSDictionary instead, e.g.
- (void) saveMyUrlsWithLabels
{
NSMutableArray* objs = [NSMutableArray arrayWithCapacity:self.myObjects.count];
for(MyObject* obj in self.myObjects) {
[objs addObject:[NSDictionary dictionaryWithKeys:#"url", #"label"
forObjects:obj.url.absoluteString, obj.userSpecifiedLabel];
}
[[NSUserDefaults standardUserDefaults] setObject:objs forKey:#"myObjects"];
}
Maybe you should do it like this:
- (MyCustomObject *)loadCustomObjectWithKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize]; // note this
NSData *myEncodedObject = [defaults objectForKey:key];
MyCustomObject *obj = nil;
// it would be even better
// to wrap this into #try-#catch block
if(myEncodedObject)
{
obj = (MyCustomObject *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
}
return obj;
}
Also note that if you want to use NSKeyedArchiver and NSKeyedUNarchiver your MyCustomObject class has to conform to NSCoding protocol. Check NSCoding protocol reference and Archives and Serializations Programming Guide.
This is another way to do it and yes you can use NSUserDefaults. Basically you get asset URL, save it and then convert it back to an asset / image
//SET IT
ALAsset *asset3 = [self.assets objectAtIndex:[indexPath row]];
NSMutableString *testStr = [NSMutableString stringWithFormat:#"%#", asset3.defaultRepresentation.url];
//NSLog(#"testStr: %# ...", testStr);
[[NSUserDefaults standardUserDefaults] setObject:testStr forKey:#"userPhotoAsset"];
[[NSUserDefaults standardUserDefaults] synchronize];
//GET IT
NSString *assetUrlStr = [[NSUserDefaults standardUserDefaults] objectForKey:#"userPhotoAsset"];
NSURL* aURL = [NSURL URLWithString:assetUrlStr];
NSLog(#"aURL: %# ...", aURL);
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library assetForURL:aURL resultBlock:^(ALAsset *asset)
{
UIImage *copyOfOriginalImage = [UIImage imageWithCGImage:[[asset defaultRepresentation] fullScreenImage] scale:1.0 orientation:UIImageOrientationUp];
imgVwPortrait.image = copyOfOriginalImage;
}
failureBlock:^(NSError *error)
{
// error handling
NSLog(#"failure-----");
}];

Objective C - UserDefaults Over Writing

I can't seem to re edit this object in my ios User Defaults. Here is my code...
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setObject:nil forKey:#"savedScoreCards2"];
Before I did this I set the key savedScoreCards to a huge 3-d dictionary, and now when I try to over write it or even set the key to nil that huge 3-d dictionary that I set up a while ago is still there. I can't seem to over write/ replace it will nothing (nil), or another huge 3-d dictionary. Any ideas?
UPDATE:
+ (void)saveCurrentScoreCard
{
//save score card
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSMutableDictionary *savedScoreCards = [[NSMutableDictionary alloc] init];
[userDefaults setObject:nil forKey:#"savedScoreCards2"];//reset at beginning
NSMutableArray *golferOneScoresu = [userDefaults arrayForKey:#"golferOneScoresArray"];
NSMutableArray *golferTwoScoresu = [userDefaults arrayForKey:#"golferTwoScoresArray"];
NSMutableDictionary *golferIconsu = [userDefaults objectForKey:#"golferIconsFirstScene"];
NSMutableArray *golferThreeScoresu = [userDefaults arrayForKey:#"golferThreeScoresArray"];
NSMutableArray *golferFourScoresu = [userDefaults arrayForKey:#"golferFourScoresArray"];
NSMutableDictionary *golferIcons2u = [userDefaults objectForKey:#"golferIcons"];
NSMutableArray *golferNamesu = [userDefaults objectForKey:#"golferNames"];
NSMutableArray *golferNames = [[NSMutableArray alloc] initWithArray:golferNamesu copyItems:YES];
NSMutableDictionary *golferIconsSceneOne = [[NSMutableDictionary alloc]initWithDictionary:golferIconsu];
NSMutableDictionary *golferIcons = [[NSMutableDictionary alloc]initWithDictionary:golferIcons2u];
NSMutableArray *golferFourScores = [[NSMutableArray alloc] initWithArray:golferFourScoresu copyItems:YES];
NSMutableArray *golferThreeScores = [[NSMutableArray alloc] initWithArray:golferThreeScoresu copyItems:YES];
NSMutableArray *golferOneScores = [[NSMutableArray alloc] initWithArray:golferOneScoresu copyItems:YES];
NSMutableArray *golferTwoScores = [[NSMutableArray alloc] initWithArray:golferTwoScoresu copyItems:YES];
NSMutableDictionary *currentScoreCard = [[NSMutableDictionary alloc] init];
[currentScoreCard setObject:golferNames forKey:#"golferNames"];
[currentScoreCard setObject:golferIconsSceneOne forKey:#"golferIconsFirstScene"];
[currentScoreCard setObject:golferIcons forKey:#"golferIcons"];
[currentScoreCard setObject:golferOneScores forKey:#"golferOneScoresArray"];
[currentScoreCard setObject:golferTwoScores forKey:#"golferTwoScoresArray"];
[currentScoreCard setObject:golferThreeScores forKey:#"golferThreeScoresArray"];
[currentScoreCard setObject:golferFourScores forKey:#"golferFourScoresArray"];
[savedScoreCards setObject:currentScoreCard forKey:#"1"];
NSLog([golferIconsSceneOne objectForKey:#"30101"]);
[userDefaults setObject:savedScoreCards forKey:#"savedScoreCards2"];
[userDefaults synchronize];
NSLog(#"SAVED SCORE CARD");
}
Use [userDefaults removeObjectForKey:#"savedScoreCards2"] if you're just trying to remove a stored value.
Also call [userDefaults synchronize]; to "flush" your changes immediately. I think the [userDefaults synchronize] is probably what you're missing.
NSUserDefaults do not save automatically when you make a change to them. Try adding this line below the ones you've posted above:
[userDefaults synchronize];
This should save any changes you've made.
As a side note, I'm not sure you can save 'nil' into NSUserDefaults; at its core I believe it's a dictionary, in which nil values cannot be set. So you might try setting an empty object, instead.
Hope this helps, let me know if you need any more information!

NSKeyedUnArchiver back to your original custom NSObject

I have an object i have made that is storing all information from twitter however i need to give it a load state so it needs to be saved to memory.
This is the code i have done so far below
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
rssParser = [[RssParser alloc] loadXMLbyURL:#"http://twitter.com/statuses/user_timeline/2smssupport.xml"];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rssParser];
[prefs setObject:data forKey:#"Tweets"];
[prefs synchronize];
NSData *olddata = [prefs dataForKey:#"Tweets"];
I need to get the olddata back to its original form as an 'RssParser'
If anyone can help out it would be ace! its been ravaging my brain the last day or so!
Does RssParser implement NSCoding? If so, you just have to do
NSData *olddata = [prefs dataForKey:#"Tweets"];
RssParser *oldRssParser = (RssParser *)[NSKeyedUnarchiver unarchiveObjectWithData:olddata];
Otherwise you should read http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/Archiving/Archiving.html%23//apple_ref/doc/uid/10000047-SW1