Cómo almacenar objetos personalizados en NSUserDefaults

Muy bien, he estado hurgando un poco y me doy cuenta de mi problema, pero no sé cómo solucionarlo. He hecho una clase personalizada para contener algunos datos. Hago objetos para esta clase, y necesito que duren entre sesiones. Antes de poner toda mi información enNSUserDefaults, pero esto no está funcionando.

-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<Player: 0x3b0cc90>' of class 'Player'.

Ese es el mensaje de error que recibo cuando pongo mi clase personalizada, "Player", en elNSUserDefaults. Ahora, he leído eso aparentementeNSUserDefaults solo almacena algunos tipos de información. Entonces, ¿cómo puedo obtener mis objetos enNSUSerDefaults?

Leí que debería haber una manera de "codificar" mi objeto personalizado y luego colocarlo, pero no estoy seguro de cómo implementarlo, ¡se agradecería su ayuda! ¡Gracias!

****EDITAR****

Muy bien, así que trabajé con el código que figura a continuación (¡Gracias!), Pero todavía tengo algunos problemas. Básicamente, el código falla ahora y no estoy seguro de por qué, porque no da ningún error. Quizás me estoy perdiendo algo básico y estoy demasiado cansado, pero ya veremos. Aquí está la implementación de mi clase personalizada, "Player":

@interface Player : NSObject {
    NSString *name;
    NSNumber *life;
    //Log of player's life
}
//Getting functions, return the info
- (NSString *)name;
- (int)life;


- (id)init;

//These are the setters
- (void)setName:(NSString *)input; //string
- (void)setLife:(NSNumber *)input; //number    

@end

Archivo de Implementación:

#import "Player.h"
@implementation Player
- (id)init {
    if (self = [super init]) {
        [self setName:@"Player Name"];
        [self setLife:[NSNumber numberWithInt:20]];
        [self setPsnCounters:[NSNumber numberWithInt:0]];
    }
    return self;
}

- (NSString *)name {return name;}
- (int)life {return [life intValue];}
- (void)setName:(NSString *)input {
    [input retain];
    if (name != nil) {
        [name release];
    }
    name = input;
}
- (void)setLife:(NSNumber *)input {
    [input retain];
    if (life != nil) {
        [life release];
    }
    life = input;
}
/* This code has been added to support encoding and decoding my objecst */

-(void)encodeWithCoder:(NSCoder *)encoder
{
    //Encode the properties of the object
    [encoder encodeObject:self.name forKey:@"name"];
    [encoder encodeObject:self.life forKey:@"life"];
}

-(id)initWithCoder:(NSCoder *)decoder
{
    self = [super init];
    if ( self != nil )
    {
        //decode the properties
        self.name = [decoder decodeObjectForKey:@"name"];
        self.life = [decoder decodeObjectForKey:@"life"];
    }
    return self;
}
-(void)dealloc {
    [name release];
    [life release];
    [super dealloc];
}
@end

Esa es mi clase, bastante directa, sé que funciona para hacer mis objetos. Aquí están las partes relevantes del archivo AppDelegate (donde llamo a las funciones de cifrado y descifrado):

@class MainViewController;

@interface MagicApp201AppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    MainViewController *mainViewController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) MainViewController *mainViewController;

-(void)saveCustomObject:(Player *)obj;
-(Player *)loadCustomObjectWithKey:(NSString*)key;


@end

Y luego las partes importantes del archivo de implementación:

    #import "MagicApp201AppDelegate.h"
    #import "MainViewController.h"
    #import "Player.h"

    @implementation MagicApp201AppDelegate


    @synthesize window;
    @synthesize mainViewController;


    - (void)applicationDidFinishLaunching:(UIApplication *)application {
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
        //First check to see if some things exist
        int startup = [prefs integerForKey:@"appHasLaunched"];
        if (startup == nil) {
//Make the single player 
        Player *singlePlayer = [[Player alloc] init];
        NSLog([[NSString alloc] initWithFormat:@"%@\n%d\n%d",[singlePlayer name], [singlePlayer life], [singlePlayer psnCounters]]); //  test
        //Encode the single player so it can be stored in UserDefaults
        id test = [MagicApp201AppDelegate new];
        [test saveCustomObject:singlePlayer];
        [test release];
}
[prefs synchronize];
}

-(void)saveCustomObject:(Player *)object
{ 
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    NSData *myEncodedObject = [NSKeyedArchiver archivedDataWithRootObject:object];
    [prefs setObject:myEncodedObject forKey:@"testing"];
}

-(Player *)loadCustomObjectWithKey:(NSString*)key
{
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
    NSData *myEncodedObject = [prefs objectForKey:key ];
    Player *obj = (Player *)[NSKeyedUnarchiver unarchiveObjectWithData: myEncodedObject];
    return obj;
}

Eeee, perdón por todo el código. Sólo trato de ayudar. Básicamente, la aplicación se iniciará y luego se bloqueará de inmediato. Lo he reducido a la parte de cifrado de la aplicación, ahí es donde se bloquea, así que estoy haciendo algo mal pero no estoy seguro de qué. La ayuda sería apreciada nuevamente, ¡gracias!

(Todavía no he podido descifrar, ya que todavía no he logrado el cifrado).

Respuestas a la pregunta(7)

Su respuesta a la pregunta