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 NSUserDefaults
aber 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
Du musst angemeldet sein, um einen Kommentar abzugeben.
Auf Ihre Spieler-Klasse, implementieren Sie die folgenden beiden Methoden (Substitution Aufrufe encodeObject mit etwas Relevantes zu Ihrem eigenen Objekt):
Lesen und schreiben von
NSUserDefaults
:Code schamlos ausgeliehen von: speichern von Klassen in nsuserdefaults
InformationsquelleAutor der Antwort chrissr
Erstelle ich eine Bibliothek RMMapper (https://github.com/roomorama/RMMapper) zu helfen, speichern Sie benutzerdefinierte Objekt in NSUserDefaults einfacher und bequemer, da die Umsetzung encodeWithCoder und initWithCoder ist super langweilig!
Markieren Sie eine Klasse als archivierbar, nutzen Sie einfach:
#import "NSObject+RMArchivable.h"
So speichern Sie ein benutzerdefiniertes Objekt in NSUserDefaults:
Bekomme ich eigene obj von NSUserDefaults:
InformationsquelleAutor der Antwort thomasdao
Wenn jemand auf der Suche für eine schnelle version:
1) Erstellen Sie eine benutzerdefinierte Klasse für Ihre Daten
2) Zum speichern von Daten benutzen Sie folgende Funktion:
3) abrufen:
Hinweis: Hier bin ich speichern und abrufen ein array der benutzerdefinierten Objekte der Klasse.
InformationsquelleAutor der Antwort Ankit Goel
Swift 4
Eingeführt, die kodierbar - Protokoll, das macht die ganze Magie, die für diese Arten von Aufgaben. Nur entsprechen Ihre benutzerdefinierten struct/class:
Und für das speichern in der Standardeinstellung können Sie die PropertyListEncoder/Decoder:
Funktioniert es wie dass für arrays und anderen container-Klassen solcher Objekte zu:
InformationsquelleAutor der Antwort Sergiu Todirascu
Unter @chrissr Antwort und läuft mit diesem code umgesetzt werden können in eine schöne Kategorie auf
NSUserDefaults
zum speichern und abrufen von benutzerdefinierten Objekte:Verwendung:
InformationsquelleAutor der Antwort Carlos P
Synchronisieren der Daten/Objekte, die Sie gespeichert haben, in NSUserDefaults
Hoffe, dies wird Ihnen helfen. Dank
InformationsquelleAutor der Antwort Muhammad Aamir Ali
Swift 3
speichern und abrufen:
InformationsquelleAutor der Antwort Vyacheslav