So speichern Sie benutzerdefinierte Objekte in NSUserDefaults

Gut, also habe ich etwas herumgestöbert, und mir wird klar mein problem, aber ich weiß nicht, wie es zu lösen ist. Ich habe eine benutzerdefinierte Klasse zu halten einige Daten. Mache ich Objekte für diese Klasse, und ich brauche Sie Letzte zwischen den Sitzungen. Vorher war ich dabei, alle meine Daten in NSUserDefaultsaber das funktioniert nicht.

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

Das ist die Fehlermeldung die ich bekomme, wenn ich meine eigene Klasse "Spieler", in der NSUserDefaults. Jetzt habe ich gelesen, dass anscheinend NSUserDefaults speichert nur einige Arten von Informationen. So wie ein bekomme ich meine Objekte in NSUSerDefaults?

Ich gelesen, dass es sollte ein Weg, um zu "codieren" mein benutzerdefiniertes Objekt und dann legen Sie es in, aber ich bin mir nicht sicher, wie es zu implementieren, würde Hilfe geschätzt werden! Danke!

****** EDIT**

Okay, so arbeitete ich mit den unten angegebenen code ein (Danke!), aber ich bin mir immer noch einige Fragen. Im Grunde ist der code stürzt ab, jetzt, und ich bin mir nicht sicher warum, denn es gibt keine Fehler. Vielleicht fehlt mir etwas grundlegendes oder bin ich einfach zu müde, aber wir werden sehen. Hier ist die Umsetzung meiner Benutzerdefinierten Klasse, "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

Umsetzung Datei:

#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

Also das ist meine Klasse, die ziemlich straight forward, ich weiß, es funktioniert bei meiner Objekte. So, hier ist der relevante Teil der Datei AppDelegate (wo rufe ich die Verschlüsselung und Entschlüsselung von Funktionen):

@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

Und dann die wichtigen Teile der Umsetzung Datei:

    #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, sorry für den ganzen code. Nur versucht zu helfen. Im Grunde, die app starten und dann Abstürzen sofort. Ich habe es eingeengt auf die ver-Teil der app, das ist, wo es kracht, also mache ich etwas falsch, aber ich bin mir nicht sicher, was. Hilfe würde geschätzt wieder, danke!!!

(Ich habe nicht bekommen, um zu entschlüsseln, aber als ich nicht gekommen Verschlüsselung funktioniert noch.)

InformationsquelleAutor der Frage Ethan Mick | 2010-02-23

Schreibe einen Kommentar