1

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.

Kanan Vora
  • 2,124
  • 1
  • 16
  • 26

4 Answers4

3

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"]];
Nirav Jain
  • 5,088
  • 5
  • 40
  • 61
  • You have made a good point, but I think the main problem he is running into is that the NSUserDefaults can only store numbers, strings, and booleans, and arrays and dictionaries of those values. It cannot directly contain objects. – WolfLink Jan 30 '13 at 02:17
  • But once he/she has complete array then we can store this value in NSUserDefaults. The another way is we can store value in NSDictionary also. – Nirav Jain Jan 30 '13 at 05:28
2

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...

Mario
  • 4,530
  • 1
  • 21
  • 32
1

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];
WolfLink
  • 3,308
  • 2
  • 26
  • 44
0

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];
Rushi
  • 4,553
  • 4
  • 33
  • 46
  • Hi Rushi, "arr_SecondClassArrayOfObjects" is populated properly but can't get the values from it. Ex; -(void)initWithArrayOfObject:(NSMutableArray *)arr_OfObjects; { arr_SecondClassArrayOfObjects = [[NSMutableArray alloc]initWithArray:arr_OfObjects]; for (Cities *ct in arr_SecondClassArrayOfObjects) { self.myLabel1.text = ct.CityName; } } So; "self.myLabel1.text = ct.CityName;" is Even "self.myLabel1.text = @"exampleCity";" is inside the constructor but outside (for ex inside ViewDidLoad) this works. What do you think the problem is? THanks, E. –  Jan 29 '13 at 22:41
  • @ervinaydin: In your above example change the for loop to: for(int i = 0; i < arr_SecondClassArrayOfObjects.count; i++) { Cities *ct = (Citties *)[arr_SecondClassArrayOfObjects.count objectAtIndex:i]; self.myLabel1.text = ct.CityName; } – Rushi Jan 30 '13 at 04:29