retain array into NSDefault? - iphone

HI all,
can we retain an array in NSDefualt?
regards
shishir

If you mean store an array, then the answer is yes. You just use the setObject:forKey: method to store it. So:
NSArray* myArray = [NSArray arrayWithObjects:#"One", #"Two", #"Three", nil];
[[NSUserDefaults standardUserDefaults] setObject:myArray forKey:#"myArrayKey"];
// much later...
NSArray* thatArray = [[NSUserDefaults standardUserDefaults] arrayForKey:#"myArrayKey];
NSLog(#"thatArray second object: %#", [thatArray objectAtIndex:1]);
// prints "thatArray second object: two"

I guess that you are asking for:
You have an array, you put it into NSUserDefaults, then later, you want to retain that array, is it right?
NSUserDefaults will not retain your array when you put it into. It just save and get data through serialization to a database
So, if you currently hold your array, you don't need to retain it any more.

Related

How can I pass a "MutableArray with full of Objects" to another class by using NSUserDefaults?

How can I pass a "MutableArray with full of Objects" to another class by using NSUserDefaults? I know how to pass "MutableArray"s but this does not work!
So;
I have a MutableArray; 'myCityObjects', and I populate it with objects; 'cities'
In each 'cities' object there are properties like cityName, cityLocation etc...
[myCityObjects addObject:cities];
Now, what I want to do is to pass this MutableArray (filled with objects) to another class by using 'NSUserDefaults';
[[NSUserDefaults standardUserDefaults] setObject: myCityObjects forKey:#"MCO"];
And in the other class,
NSMutableArray *getMyCityObjects = [[NSArray alloc] init];
getMyCityObjects = [[NSUserDefaults standardUserDefaults] mutableArrayValueForKey:#"MCO"];
But it doesn't work! I cannot get myCityObjects in the other class, "getMyCityObjects" is empty. How can I fix that?
Thanks,
E.
NSUserDefaults always returns immutable objects, even if the original object was mutable.
In your first View, You can save value in NSUserDefaults like this:
NSMutableArray *arr= [NSMutableArray arrayWithObjects:#"asd",#"dsa",nil];
[[NSUserDefaults standardUserDefaults] setObject:arr forKey:#"MCO"];
After this in another view, you can retrieve value from NSUserDefaults in this way.
NSMutableArray *abc = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"MCO"]];
Your array is nil because the objects in it (your custom objects) can't be serialised.
Please take a look at the NSCoding protocol. Objects you want to serialise (eg for writing to NSUserDefaults) must implement the methods -encodeWithCoder: and -initWithCoder.
I'm sure you'll find how this is rather easily done searching for the terms I gave you...
I have run into this problem before. The problem with the NSUserDefaults is that it can only contain strings, numbers, and booleans, and arrays or dictionaries of those types of values. My solution is to get around that by storing all the properties in NSDictionaries.
Create two class functions on your "cities" class (I'm calling it CityClass):
+(NSDictionary *)dictionaryFromCity:(CityClass *)myCity {
NSDictionary *returnDict = #{#"keyForIntProperty" : myCity.intProperty, #"keyForFloatProperty" : myCity.floatProperty, #"keyForNSStringProperty", myCity.NSStringProperty"};
return returnDict;
}
+(CityClass *)cityFromDictionary:(NSDictionary *)myDict {
CityClass *returnCity = [[CityClass alloc] init];
returnCity.intProperty = [[myDict objectForKey:#"keyForIntProperty"] intValue];
returnCity.floatProperty = [[myDict objectForKey:#"keyForFloatProperty"] floatValue];
returnCity.NSStringProperty = [myDict objectForKey:#"keyForNSStringProperty"];
//any other setup for the CityClass
return returnCity;
}
Now you can store and retrieve your objects without a problem using the new functions:
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
//store a CityClass object
NSDictionary *storageDict = [CityClass dictionaryFromCity:cityToStore];
[defaults setObject:storageDict forKey:#"keyForCity"];
//retrieve a CityClass object
NSDictionary *retrieveDict = [defaults objectForKey:#"keyForCity"];
CityClass *retrievedCity = [CityClass cityFromDictionary:retrieveDict];
What you can do here is create a Constructor in your other class for e.g.
-(void)initWithArrayOfObject:(NSMutableArray *)arr_OfObjects;
{
arr_SecondClassArrayOfObjects = [[NSMutableArray alloc]initWithArray:arr_OfObjects];
}
From your first class send this array as :
[objOfSecondClass initWithArrayOfObject: myCityObjects];

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;

'Program received signal: SIGABRT' when inserting object to NSMutableArray

When I try to insert an object to my NSMutableArray I am getting a 'Program received signal: SIGABRT' error, however I don't understand why.
Here is my code, specifically it's the insertObject:value that is causing the error.
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionary];
[myDictionary setValue:valueName.text forKey:kValueName];
[myDictionary setObject:subValuesList forKey:kSubValuesList];
MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
int position = appDelegate.position;
NSMutableArray *valuesList = [[NSUserDefaults standardUserDefaults] objectForKey:kValuesArray];
[valuesList insertObject:myDictionary atIndex:position];
Values returned from NSUserDefaults are immutable, even if you set a mutable object as the value.
You need to make a mutable copy after you retrieve the array from NSUserDefaults. Luckily for you, NSArray conforms to the NSMutableCopying protocol, so you just have to send a mutableCopy message to the array:
NSMutableArray *valuesList = [[[NSUserDefaults standardUserDefaults] objectForKey:kValuesArray] mutableCopy];
Keep in mind that you own the object returned by mutableCopy as per the Memory Management Rules. In other words, you need to release it when you are done with it.
You have to save and retrieve the array using NSData. Possible dup.
Possible to save an integer array using NSUserDefaults on iPhone?

Port array of strings to array of dictionaries each containing a string

I'm trying to port the strings in an array into an array of dictionaries where each dictionary contains one of the strings and a boolean. Hopefully this makes sense, but I'll try and make a diagram:
At the moment I have:
<array>
-<string1>
-<string2>
...
</array>
But I want:
<array>
-<dictionary1>
--<string1>
--<bool>
-</dictionary1>
-<dictionary2>
--<string2>
--<bool>
-</dictionary2>
...
</array>
I've tried creating a loop to cycle through the array of strings, but it doesn't seem to work.
The ultimate goal is to save this new array of dictionaries to the NSUserDefaults (which I'm also fairly unfamiliar with). This is what I have so far, and any help would be much appreciated!
// Get the current array from the user defaults.
NSArray *tempArray = [[NSUserDefaults standardUserDefaults] objectForKey:#"myArrayKey"];
self.myArray = [tempArray mutableCopy];
// Loop to cycle through the array of strings
for(int i = 0; i < [aList count]; i++)
{
// Boolean to go in the dictionary with the string.
checked = NO;
// Create a dictionary, and set it with two objects and two keys.
//First object is the string in the array we are cycling through, the second object is the boolean.
NSDictionary *tempDict = [[NSDictionary alloc] initWithObjectsAndKeys:[aList objectAtIndex:i], #"Title", checked, #"checked", nil];
// Add this dictionary to the new array of dictionaries.
[self.myArray addObject:tempDict];
// This NSLog gives me 0 - but gives me 0 seven times (the number of items in the array I am cycling through) so it is definitely cycling through the array.
NSLog(#"My Array Count: %i", [myArray count]);
// Release the tempDict.
[tempDict release];
}
// Write this new array of dictionaries back to NSUseDefaults.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:myArray forKey:#"myArrayKey"];
[defaults synchronize];
As Daniel pointed out (and I shortly realised through some tests), the fact that the array from NSUserDefaults was nil stopped it from working.
How about inserting a line
[tempDict retain];
next
[self.myArray addObject:tempDict];

how to check nsuserdefaults is empty or not

i am getting a list of items from sqlite database and place them in an array.
i need to get this array first time my app runs.
for this i am saving this array into NSuserdafaults.
my code is like this
if ([[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"]) {
[[NSUserDefaults standardUserDefaults] setObject:appdelegate.categoriesList forKey:#"categories"];
NSLog(#"categorylist>>>>>> %#",appdelegate.categoriesList);
}
categoriesArray = [[NSMutableArray alloc]init];
categoriesArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"] mutableCopy];
then it not entered into if condition.
and if i try with not equal like this.
if (![[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"]) {
[[NSUserDefaults standardUserDefaults] setObject:appdelegate.categoriesList forKey:#"categories"];
NSLog(#"categorylist>>>>>> %#",appdelegate.categoriesList);
}
categoriesArray = [[NSMutableArray alloc]init];
categoriesArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"] mutableCopy];
then enter for every build and run.
But i need this for first build and run i mean at installing time.
can any one please help me.
Thank u in advance.
(let me add comment if any one did n't understand my question)
categoriesArray = [[NSMutableArray alloc]init];
categoriesArray = [[[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"] mutableCopy];
The lines above create a leak: you first allocate one array, and then you immediately assign a different array to the same pointer that was keeping track of the array that you allocated. After the second line, you have no way to release the first array.
As for the main question, I suspect that the check
if (![[NSUserDefaults standardUserDefaults] arrayForKey:#"categories"]) {
succeeds every time because there's never a value written for the key #"categories". I see that the lines inside that conditional block try to write a value, but appdelegate.categoriesList may well be nil.