Tudo bem, então eu ando bisbilhotando e percebo o meu problema, mas não sei como consertá-lo. Eu criei uma classe personalizada para armazenar alguns dados. Eu faço objetos para essa classe e preciso que eles durem entre as sessões. Antes de colocar todas as minhas informações NSUserDefaults, mas isso não está funcionando.
-[NSUserDefaults setObject:forKey:]: Attempt to insert non-property value '<Player: 0x3b0cc90>' of class 'Player'.
Essa é a mensagem de erro que recebo quando coloco minha classe personalizada, "Player", no NSUserDefaults. Agora, li que aparentemente NSUserDefaultsapenas armazena alguns tipos de informações. Então, como eu coloco meus objetos NSUSerDefaults?
Eu li que deveria haver uma maneira de "codificar" meu objeto personalizado e depois colocá-lo, mas não sei como implementá-lo, a ajuda seria apreciada! Obrigado!
****EDITAR****
Tudo bem, então trabalhei com o código fornecido abaixo (obrigado!), Mas ainda estou tendo alguns problemas. Basicamente, o código falha agora e não sei por que, porque não dá nenhum erro. Talvez esteja sentindo falta de algo básico e esteja cansado demais, mas vamos ver. Aqui está a implementação da minha classe Custom, "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
Arquivo de implementação:
#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
Então essa é a minha aula, bem direta, eu sei que funciona na criação de meus objetos. Então, aqui estão as partes relevantes do arquivo AppDelegate (onde eu chamo as funções de criptografia e descriptografia):
@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
E então as partes importantes do arquivo de implementação:
#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, desculpe por todo o código. Apenas tentando ajudar. Basicamente, o aplicativo será iniciado e falhará imediatamente. Eu o reduzi à parte de criptografia do aplicativo, é onde ele falha, então estou fazendo algo errado, mas não sei ao certo o que. Ajuda seria apreciada novamente, obrigado!
(Ainda não descriptografei, pois ainda não comecei a criptografar.)