Storing NSMutableArray full of custom object into NSUserDefaults

Discussion in 'iOS Programming' started by playboy16, Jun 28, 2009.

  1. playboy16 macrumors newbie

    Joined:
    Jun 23, 2009
    #1
    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!
     
  2. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
  3. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #3
    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."
     
  4. playboy16 thread starter macrumors newbie

    Joined:
    Jun 23, 2009
    #4
    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.
     
  5. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #5
    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.
     
  6. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #6
    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.
     
  7. playboy16 thread starter macrumors newbie

    Joined:
    Jun 23, 2009
    #7
    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.

    Great. I will add these fields as properties and give er a go. thanks!
     

Share This Page