• 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

Core Data, doppelter Datensatz wegen save

Lene85

Jonagold
Registriert
22.05.11
Beiträge
23
Hi Leute,

Ich mache gerade eine App, die core data verwendet. Der Großteil aller Daten liegt schon vor, wenn der Anwender die App startet. Ich erzeuge sie in so:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

NSManagedObject *S1 = [NSEntityDescription insertNewObjectForEntityForName:@"Section" inManagedObjectContext:self.managedObjectContext];
[S1 setValue:NSLocalizedString(@"S1", nil) forKey:@"name"];

... usw ...usw.. (insgesamt etwa 300 kleine Objekte)!

}


Die Daten sind auf die Weise nicht persistent, aber sie werden ja bei jedem launchen der App neu erzeugt. Das ist OK, aber der Anwender soll auch die möglichkeit die Daten zu Editieren. Dazu habe ich die Folgende Methode geschrieben:

- (void)newDetail:(Detail *)detail{
Detail *newDetail = [[Detail alloc]init];
newDetail = (Detail *)[NSEntityDescription insertNewObjectForEntityForName:@"Detail" inManagedObjectContext:self.managedObjectContext];
[newDetail setValue:detail.text forKey:@"text"];
[newDetail setValue:favorites forKey:@"category"];
}

Das läuft auch. Aber die so erzeugeten Daten werden ja nicht beim nächsten launchen neu erzeugt. Sie gehen also verlohren, wenn ich nicht die "save" Nachricht sende:

if (![[fetchedResultsController managedObjectContext] save:&error]) {...

Auf die Weise mache ich aber direkt alle Daten persisten. Auch die, die ich in der Methode: " - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;" erzeugt habe. Wenn ich die App dann neu launche wir die Methode natürlich wieder ausgeführt. Die logische Folge: Ein doppelter Datensatz!

Hat jemand eine Idee?
Gibt es eine Möglichkeit sie "save-Methode" auf einzelne Objekte anzuwenden?

Vielen Dank und LG,
Lene85
 
Also ich versteh nicht so ganz was du vorhast, was du so beschreibst hört sich aber völlig normal an. Ich denke du müsstest beim Start der Anwendung schauen, ob die "Daten" schon persistent sind. Falls ja, lädst du sie und falls nein erstellst du neue (so wie du das beschrieben hast). Wenn du bei jedem Start die Daten erstellst und persistent machst ist doch logisch, dass Duplikate entstehen.
 
Hi,

vielen Dank für deine schnelle Antwort!

Stimmt, ich kann zuerst prüfen, ob die Daten schon existieren. In der Docu ich habe dazu folgendes gefunden:

If you are using iOS or creating a non-document-based application for Mac OS X, you can add a check on application launch to determine whether a file exists at the location you specify for the application’s store. If it doesn't, you need to import the data. For an iOS-based example, see CoreDataBooks.

In CoreDataBooks habe ich dann leider vergeblich nach den entsprechenden Codzeilen gesucht.

Ich weiß, wie ich prüfen kann, ob sich hinter einem bestimmten Pfad eine bestimmte Datei verbirgt. Trotzdem kann ich mir nicht ausmalen, wie ich die Anleitung aus Doku (s.o.) umsetzten soll.
Mein CoreData-File heißt: "Verzeichnis.xcdatamodeld" Wie ändert sich die Dateiendung nach dem Kompilieren?

Wie wäre es damit:

NSString* documentsPath = @"MeinPfad";
NSString* dateiname = @"Verzeichnis.DateiendungNachKompilieren";
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:dateineme];

Wie würdest du es machen?
Bitte sei etwas nachsichtig mit mir. Ich bin nicht nur Anfängerin in Objektive C, sondern beschäftige mich überhaupt erst seit ein paar Monaten mit Programmieren.

LG
Lene85
 
OK, ich versuche nachsichtig zu sein ;-) Ich habe aber immer noch nicht so richtig verstanden, was du überhaupt vorhast. Was meinst du mit Datei? Die eigentliche Datenbank(datei)?

Du brauchst eine URL zu der Datenbankdatei:
Code:
NSURL *storeURL = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"MyDatabase.sqlite"]];
und versuchst dann daraus einen NSPersistentStoreCoordinator zu erstellen, falls das fehlschlägt, ist keiner vorhanden und muss erst erstellt werden.

Ich weiß jetzt nicht mehr im Detail wie ich das gemacht habe, was mir aber sehr geholfen hat, war zum einen die CoreData-Dokumentation und insbesondere die "Locations"-Beispiel-App von Apple. Schau da mal rein. Da wird sehr schön gezeigt, wie man einen NSPersistentStoreCoordinator zurückgibt bzw. erstellt, falls von keiner vorhanden ist.

Link zu Locations:
http://developer.apple.com/library/...on/Intro.html#//apple_ref/doc/uid/DTS40008406
 
Hi JamesLaFleur!
Sorry, dass ich nicht mehr geantwortet habe. Mein Leben verschluckt mich manchmal.

Hier ist meine Endversion:

NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* foofile = [documentsPath stringByAppendingPathComponent:@"VerzeichnisMitVorauswahl.sqlite"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:foofile];

if (fileExists) {
}else{

//Hier weren die Coredata-Objekte erstellt.

}


Funktioniert prima!


LG und herzilchen Dank!