273 votes

Comment stocker des objets personnalisés dans NSUserDefaults

Bon, j'ai fait quelques farfouillé, et je me rends compte de mon problème, mais je ne sais pas comment le résoudre. J'ai fait une classe personnalisée pour conserver certaines données. - Je créer des objets de cette classe, et j'ai besoin d'eux pour la dernière entre les sessions. Avant je mettais toutes mes informations dans NSUserDefaults, mais ce n'est pas de travail.

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

C'est le message d'erreur que j'obtiens lorsque j'ai mis ma classe personnalisée, "le Joueur", dans le NSUserDefaults. Maintenant, j'ai lu qu'apparemment NSUserDefaults seulement les magasins de certains types de renseignements. Alors, comment un-je obtenir mes objets en NSUSerDefaults?

J'ai lu qu'il devrait y avoir une façon de "coder" mon objet personnalisé, puis la mettre, mais je ne suis pas sûr de la façon de la mettre en œuvre, de l'aide serait apprécié! Merci!!!!

*EDIT*

Bon, alors j'ai travaillé avec le code donné ci-dessous (Merci!), mais j'ai encore quelques questions. En gros, le code se bloque maintenant et je ne suis pas sûr pourquoi, parce qu'il ne donne pas toutes les erreurs. Peut-être que je suis absent quelque chose de base et je suis trop fatigué, mais nous allons voir. Ici est la mise en œuvre de ma classe Personnalisée, "Joueur":

@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

La Mise En Œuvre De Fichier:

#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

Donc, c'est ma classe, assez simple, je sais qu'il travaille en faisant de mes objets. Donc, voici les parties pertinentes de l'AppDelegate fichier (où j'appelle le chiffrement et déchiffrer les fonctions):

@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

Et puis les parties importantes de la mise en œuvre de fichier:

    #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, désolé tout le code. Juste essayer d'aider. Fondamentalement, l'application se lance et se bloque immédiatement. J'ai rétréci vers le bas pour le chiffrement de l'appli, c'est là que ça plante, donc je suis en train de faire quelque chose de mal mais je ne suis pas sûr de ce que. De l'aide serait apprécié encore une fois, merci!

(Je n'ai pas eu l'occasion de décrypter pourtant, comme je n'ai pas encore eu le cryptage de travail).

521voto

chrissr Points 5622

Sur votre catégorie de joueur, implémenter les deux méthodes suivantes (son remplacement par des appels à encodeObject avec quelque chose de pertinent à votre propre objet) :

Lecture et l’écriture de `` :

Code emprunté sans vergogne : sauver la classe nsuserdefaults

36voto

thomasdao Points 1766

J’ai créer une bibliothèque RMMapper (https://github.com/roomorama/RMMapper) pour aider à sauver l’objet personnalisé en NSUserDefaults plus facile et plus pratique, parce que la mise en œuvre d’encodeWithCoder et initWithCoder est super ennuyeux !

Pour marquer une classe comme archivables, il suffit d’utiliser :``

Pour enregistrer un objet personnalisé en NSUserDefaults :

Pour obtenir d’articles personnalisés de NSUserDefaults :

9voto

Carlos P Points 1625

Prenant la réponse de @chrissr et courir avec elle, ce code peut être implémenté dans une catégorie sympa sur `` pour enregistrer et récupérer des objets personnalisés :

Utilisation :

6voto

MuhammadAamirALi Points 2555

Synchroniser le données/objet que vous avez enregistré dans NSUserDefaults

Espérons que cela vous aidera. Merci

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X