Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

playboy16

macrumors newbie
Original poster
Jun 23, 2009
13
0
I want to store a structure that looks like this into NSUserDefaults

NSMutableArray
NSMutableArray
Custom object

How do I do this?

I know NSUserDefaults only saves NSArrays. How can I convert and my structure?

Thanks!
 
I know NSUserDefaults only saves NSArrays. How can I convert and my structure?
NSUserDefaults saves more than just NSArray types. As explained in the NSUserDefaults Class Reference Overview, "A default’s value must be a property list, that is, an instance of (or for collections a combination of instances of): NSData, NSString, NSNumber, NSDate, NSArray, or NSDictionary." It goes on to state, "If you want to store any other type of object, you should typically archive it to create an instance of NSData. For more details, see User Defaults Programming Topics for Cocoa."
 
Ok I am trying to make my class conform to the NSCoding protocol.

It sits inside 2 NSMutableArray's. It does not throw any error messages or anything and if I debug the initWithCoder method everything seems to be ok. But I get a Program received signal: “EXC_BAD_ACCESS” somewhere.

Here is how I save the NSMutable array with my objects. highScoresArray is a NSMutableArray that has another NSMutableArray that has the custom object.
Code:
NSString *archivePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"HighScore.archive"];
	
	BOOL result = [NSKeyedArchiver archiveRootObject:highScoresArraytoFile:archivePath];
Here is how I try to retrieve it back.

Code:
NSString *archivePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"HighScore.archive"];
	
	if ((highScoresArray = [NSKeyedUnarchiver unarchiveObjectWithFile:archivePath]) == nil) {
		highScoresArray = [[NSMutableArray alloc] init];
	}

Here is the definition of my custom class.

.h

Code:
@interface UserHighScore : NSObject <NSCoding> {
	NSString *name;
	NSString *drink;
	NSNumber *score;

}

@implementation

-(void)encodeWithCoder:(NSCoder *)encoder
{
	[encoder encodeObject:name forKey:@"Name"];
	[encoder encodeObject:drink forKey:@"Drink"];
	[encoder encodeObject:score forKey:@"Score"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
	if (self=[super init]){
		name = [decoder decodeObjectForKey:@"Name"];
		drink = [decoder decodeObjectForKey:@"Drink"];
		score = [decoder decodeObjectForKey:@"Score"];
	}
	return self;
}
I have tried to make just one custom object without putting it inside an array and in the debugger it says the string is invalid.
 
I have tried to make just one custom object without putting it inside an array and in the debugger it says the string is invalid.
Which string? Can you give us more details of the error and where this is occurring? Is this when you are trying to add your single UserHighScore object to NSUserDefaults?

P.S. Also, please use the [ CODE ][ /CODE ] tags (remove the spaces) to enclose code snippets. These tags are accessible via the # icon in the toolbar.
 
You need to retain the objects from decodeObjectForKey if assigning it directly to a variable. If you're using properties (which you should) then you don't need to.
 
Which string? Can you give us more details of the error and where this is occurring? Is this when you are trying to add your single UserHighScore object to NSUserDefaults?

P.S. Also, please use the [ CODE ][ /CODE ] tags (remove the spaces) to enclose code snippets. These tags are accessible via the # icon in the toolbar.

When I try to access one of the string in the user object after I have received it that is when it says it is invalid. I am not using NSUserDefaults. I am using archiving.

You need to retain the objects from decodeObjectForKey if assigning it directly to a variable. If you're using properties (which you should) then you don't need to.

Great. I will add these fields as properties and give er a go. thanks!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.