• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Die Bildungsoffensive hier im Forum geht weiter! Jetzt sollen Kreativität und technische Möglichkeiten einen neue Dimension erreichen. Das Thema in diesem Monat lautet - Verkehrte Welt - Hier geht es lang --> Klick

Array speichern und wieder laden

branco145

Rheinischer Winterrambour
Registriert
26.07.09
Beiträge
933
Hallo Leute,

ich habe in meine App eine Favoriten Funktion eingebaut. Ich rufe ein Array auf, speichere es bisher so:

Code:
//get the documents directory:
            NSArray *paths = NSSearchPathForDirectoriesInDomains
            (NSDocumentDirectory, NSUserDomainMask, YES);
            NSString *documentsDirectory = [paths objectAtIndex:0];
            //make a file name to write the data to using the
            //documents directory:
            NSString *fullFileName = [NSString stringWithFormat:@"%@/arraySaveFile", documentsDirectory];
            
            
            //this statement is what actually writes out the array
            //to the file system:
            [appDelegate2.savedText writeToFile:fullFileName atomically:NO];

Klappte auch eine Zeit lang, dann plötzlich nicht mehr.

Meine Frage: Wie speichere ich ein Array (richtig) in eine Datei, um das Array bei App Start immer wieder laden zu können?
 
Du solltest erst mal das atomically:NO]; auf YES setzen, ist auf jeden Fall von Vorteil. Und das Array könne man auch als plist abspeichern ;)
 
Danke. Habe es jetzt so gemacht:

Speichern des Arrays:
Code:
NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
[prefs setObject:appDelegate.savedText forKey:@"myArray"];
[prefs synchronize];
NSLog(@"Saved array to NSUserDefaults");

Laden des Arrays:
Code:
NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
appDelegate.savedText = [prefs objectForKey:@"myArray"];
 
Und wieder funktioniert es nicht mehr. Speichern tut er anscheinend, aber in der Favoriten-Tabelle erscheint nichts. Was kann das sein?

EDIT: Im Simulator funktioniert es wieder. Auf dem Gerät immer noch nicht...
 
Zuletzt bearbeitet:
Wo, wann und mit welchem Ergebnis machst Du den retrieve? Und warum nutzt Du bspw. nicht arrayForKey:, dictionaryForKey:, stringArrayForKey:, o.ä.?
 
Ich habe ein Liste mit Einträgen mit einem NSMutableArray in einer Tabelle. Klickt man rauf, kommt man in eine Detailansicht. Dort kann man den Text mit:

Code:
//Das "Favoriten" Array ist im AppDelegate, weil ich es auch an anderen Orten noch benötige
BwAAppDelegate *appDelegate = (BwAAppDelegate *)[[UIApplication sharedApplication] delegate];
//Fügt den Text zu dem "Favoriten" array hinzu
[appDelegate.savedText addObject:rezeptText];
		
//Speichert das "Favoriten" Array aus dem AppDelegate
		NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
		[prefs setObject:appDelegate.savedText forKey:@"myArray"];
		[prefs synchronize];
		NSLog(@"Saved array to NSUserDefaults");

speichern.

In einem zusätzlichem Controller ist eine Tabelle. Diese soll die gespeicherten Einträge anzeigen.
Code:
- (void)viewDidLoad {
	[super viewDidLoad];

	BwAAppDelegate *appDelegate = (BwAAppDelegate *)[[UIApplication sharedApplication] delegate];   
	NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
	appDelegate.savedText = [prefs objectForKey:@"myArray"];
}

Dieser Code funktioniert komischerweise manchmal im Simulator und manchmal nicht... auf dem iPhone selbst, gar nicht.
 
Nein, das ist doch das selbe in grün.

Die Frage ist: Auf welchen Event, Methode, Action, oder was auch immer machst Du das?
Und welches Ergebnis bekommst Du dann? Hat das geklappt? Welche Werte hast Du? etc.
Lass das mal jeweils ausgeben.

Btw: Datenhaltung/-operationen macht man nicht im View.
 
Ich glaube ich habe den Fehler gefunden. Im App Delegate lade ich jetzt ApplicationDidFinishLaunching... Methode das NSUserDefaults
Code:
NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];
savedText = [prefs objectForKey:@"myArray"];

Natürlich ist der Wert am Anfang null, da nichts gespeichert. Er lädt also immer null Einträge. Wenn ich nun was speichern will, gibt er als gespeichertes Objekt null aus.Wenn ich den Code aber weglasse funktioniert es (natürlich ohne Speichern des Arrays).

Ich muss also nur beim Start herausfinden ob das UserDefaults leer ist... mal sehen ob ich das hinkriege...

So funktioniert es (bis jetzt noch :D), sowohl im Simulator als auch auf dem iPhone, mal sehen wie sich das entwickelt...

Code:
NSUserDefaults *prefs =[NSUserDefaults standardUserDefaults];

	if([prefs objectForKey:@"myArray"] == nil)
	{
		NSLog(@"Saved array is empty");
	}
	
	else {
		savedText = [prefs objectForKey:@"myArray"];
		NSLog(@"Saved array is not empty and was loaded");
	}
 
Was soll das werden? Warum benutzt Du nicht die Registration Domain?
 
Userdefaults sollten immer einen Standardwert haben (registerDefaults).
Dann brauchts auch keine Fehlerabfrage.

Dein allgemeines Problem "Funktioniert nicht mehr" ist aber nur aufgeschoben mit dem Wechsel auf die Userdefaults.
Diese sind auch nur eine Plist.

Wenn das Laden nicht mehr geht, wird wohl was nicht richtig gespeichert werden.
Versuchst du irgendwelche Objekte die nil sind zu speichern?
Das klappt nicht, da nil zur Terminierung von Arrays und Dictionarys verwendet wird.

Eine Fehlerabfrage beim speichern wäre evtl. also sinnvoller als die Speichermethode zu ändern.
 
"Oh", entschuldige wenn ich deine Programmiererehre gekränkt haben sollte.
Sei es durch falsche Wortwahl, oder durch voreiliges Schließen auf nicht einsehbare Code durch das Verhalten des Selbigen.

Mir ging es darum:
Code:
    NSArray *myArray = [NSArray arrayWithObjects:aDate, aValue, aString, nil];

In seinem Code kommt eben beim Dateinamen fürs Speichern "Array" vor.
Ist hier ein Objekt nil, findet keines der nachfolgenden Objekte mehr seinen Weg in die Datei.
Sooo abwegig ist der Gedanke ja wohl nicht, dass das Array einfach befüllt wird bis es ein nil findet, oder?

Könnte durchaus ein Grund sein, warum beim Laden nicht mehr das erwartete Resultat herauskommt.
 
Er benutzt aber, so weit ich das hier sehen kann, nur addObject:.

MacApple
 
In seinem Code kommt eben beim Dateinamen fürs Speichern "Array" vor.
Ist hier ein Objekt nil, findet keines der nachfolgenden Objekte mehr seinen Weg in die Datei.
Sooo abwegig ist der Gedanke ja wohl nicht, dass das Array einfach befüllt wird bis es ein nil findet, oder?
Könnte durchaus ein Grund sein, warum beim Laden nicht mehr das erwartete Resultat herauskommt.
Nein. Der Mechanismus beruht auf Dictionaries und Arrays. Das ist gar kein Problem.

P.S. Das eigentliche Problem ist der Fragesteller. Ich weiss echt nicht, was das Katz-und-Maus-Spiel soll.
 
Zuletzt bearbeitet:
Er benutzt aber, so weit ich das hier sehen kann, nur addObject:.
MacApple

Es ist ja recht wenig Info da.
Ich bezog mich eher auf sein erstes Post, als er noch nicht mit den Userdefaults gearbeitet hat.

Mache ich folgendes:

Code:
NSNumber *value1 = nil;
NSNumber *value2 = [NSNumber numberWithInt:2];

NSDictionary *saveFile = [NSDictionary withObjectsAndKeys:value1, @"Value1Key",
                                                                                                                    value2, @"Value2Key",
                                                                                                                    nil];

[saveFile writeToFile:path atomically:NO];
Dann wird value2 nicht auf der Platte landen. Laden kann ich es somit auch nicht mehr.
 
Zuletzt bearbeitet: