views:

419

answers:

5

I'm confused about NSUserDefaults on the iPhone.

I come from a C / asm background and the Objective-C stuff has been a learning experience.

I'm currently using NSUserDefaults to store some strings (for the names in a highscore table). I want to start implementing a "Save Game" type feature so if the user gets a call or exits out of the game for a moment, they can come back to it.

To recover the game, I've got a couple of BOOL flags, a couple of ints to store some necessary variables, but I'm stuck at an array I need to store.

I have a 50 element array of unsigned chars. I could move it to ints if it would make things easier, but I'm just not seeing it.

To work with NSUserDefaults I can setBool (already doing that), setFloat (again, already doing that), setInteger, and setObject.

Obviously I could declare keys for each element of the array and store them one by one with setInteger but that's really kludgy. What's the best way to tackle this? Instead of an array of unsigned chars, I somehow try to use an NSObject? Are there any good tutorials on NSObjects that I can read through to understand it better?

+5  A: 

Would Property Lists fit better with what you are trying to achieve?

You can create dictionary, store value for each setting or an array, and then dump it to Property List. You can easily read them back or update the values based on keys.

http://developer.apple.com/documentation/Cocoa/Conceptual/PropertyLists/...

stefanB
Yes, typically you'd use NSUserDefaults for preferences (like choosing imperial vs metric units), and store your app's data in a separate file using serialized property lists, sqlite, Core Data, etc.
Marc Charbonneau
Agreed, user defaults is for prefs, but data should be stored elsewhere, like a plist in "~/Library/Application Support/MyApp/" for example.
Quinn Taylor
On iPhone, there are obviously different conventions for storing data, since the structure is very different. Consult the relevant iPhone programming guides for details on storing files for your app.
Quinn Taylor
On iPhone you only have access within application bundle, but you can still use any of the methods (prop lists, sqlite, core data etc).
stefanB
Ok, I will look into all of this.
K2Digital
+2  A: 

You can pass an NSArray or an NSDictionary to NSUserDefaults with setObject:forKey:. It works just fine. Obviously, your array of unsigned chars would have to become an an NSArray of NSNumbers, which implies some overhead, but it's probably your easiest option.

Jim Puls
+1  A: 

Try using an NSData object, which can be directly stored to NSUserDefaults

[[NSUserDefaults standardUserDefaults] setObject:[NSData dataWithBytes:array length:len]
                                          forKey:@"someArray"];
cobbal
A: 

Whoa there, you should really look into using Core Data (or just sqllite) to store game state. NSUserDefaults is for what is says - defaults, configuration settings. It is not really meant to store largish chunks of binary data.

Kendall Helmstetter Gelner
A: 

To convert a 50 element C array of unsigned chars in to an NSArray which you can store in a NSUserDefaults using:

NSMutableArray* a = [NSMutableArray new];
for ( int i = 0; i < 50; ++i ) {
    [a addObject:[NSNumber numberWithInteger:yourArray[i]]];
}
[[NSUserDefaults standardUserDefaults] setObject:a forKey:@"theArray"];
[a release];

to get it back:

NSArray* a = [[NSUserDefaults standardUserDefaults] objectForKey:@"theArray"];
for ( int i = 0; i < 50; ++i ) {
    yourArray[i] = [[a objectAtIndex:i] integerValue];
}

There is certainly no problem with using NSUserDefaults to store your game state, not when it is so small. If your game state was humoungous, you might want to investiage storing it as a plist file, but NSUserDefaults will not break a sweat handling this trivial amount of data.

Peter N Lewis
Thank you for the code and the recommendation. I'll give it a shot.
K2Digital