Brauche Hilfe bei iPhone App

L

Lightning89

Neues Mitglied
Thread Starter
Dabei seit
05.05.2010
Beiträge
16
Reaktionspunkte
0
Hallo Leute,

kann mir jemand von euch sagen, wie ich hinzugefügte Daten in einem TableView speichern kann? Die Einträge werden während der Laufzeit hinzugefügt und sollen nach dem Beenden des Programms immer noch gespeichert sein.

Hat jemand von euch Erfahrung mit so etwas?

Danke für eure Hilfe.

Schöne Grüße
 
CoreData ist das Zauberwort. Schau dir mal das Apple Beispiel an.
Da kannst du eigentlich so ziemlich alles benutzen.
 
Wenn Du nur wenige Daten speichern musst, dann lohnt sich der Aufwand für Core Data nicht. In dem Fall würde ich mit .plist Dateien arbeiten.
 
Wenn Du nur wenige Daten speichern musst, dann lohnt sich der Aufwand für Core Data nicht. In dem Fall würde ich mit .plist Dateien arbeiten.

Hi, danke für eure Antworten. :)

Also ich will wirklich nicht viele Daten speichern, aber wie geht das mit der .plist?
Ich bin noch ein totaler Anfänger in diesem Gebiet und bin dankbar für jede Hilfe von euch. :)
 
Ne andere Möglichkeit wäre auch die Klasse NSUserDefaults, wenn es nur wenige Daten sind.
Ansonsten schau dir mal www.x02100.de an, da gibts, wie ich finde, n ziemlich guten Podcast zu so ziemlich allen Aspekten bei der iPhone- und Macprogrammierung.
 
Ne andere Möglichkeit wäre auch die Klasse NSUserDefaults, wenn es nur wenige Daten sind.
Ansonsten schau dir mal www.x02100.de an, da gibts, wie ich finde, n ziemlich guten Podcast zu so ziemlich allen Aspekten bei der iPhone- und Macprogrammierung.

Danke für deinen Tipp, hat mir sehr geholfen.
Ich habe aber leider noch ein Problem, und zwar speichert es nicht, wenn ich von einem ersten View mit einem Button zum zweiten gehe und im zweiten View sich das TableView befindet. Die Einträge kann ich ohne große Probleme zum TableView hinzufügen, es speichert jedoch nichts ab. Beide View's sind UIView Klassen, könnte dass das Problem sein?

Für eure Antworten danke ich jetzt schon :)

Grüße
 
Für welchen Ansatz hast du dich denn entschieden? Die Aussage, dass es nicht speichert, ist nich so wirklich erhellend. Dass dieses Problem von der Klasse UIView herrührt, kann ich mir nur schwer vorstellen.
 
So habe ich es im appDelegate.m gemacht:

-(void)applicationWillTerminate: (UIApplication *)application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *archiv = [NSKeyedArchiver archivedDataWithRootObject:secondViewController.entries];
[defaults setObject:archiv forKey:mad:"entries"];
}

und so im secondView.m

- (id)initWithCoder: (NSCoder *)decoder {
self = [super initWithCoder: decoder];
if (self != nil) {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *archiv = [defaults objectForKey: @"entries"];
if (archiv) {
NSArray *array = [NSKeyedUnarchiver unarchiveObjectWithData:archiv];
self.entries = [NSMutableArray arrayWithArray: array];
} else {
self.entries = [NSMutableArray array];
}

}
return self;
}

Ist es jetzt verständlicher? Oder wäre es besser, wenn ich den Quellcode mal insgesamt anhänge?
 
Ich denke mal, das komplette Projekt wäre, wenn du überhaupt was anhängen willst, am Sinnvollsten.

Ansonsten fällt mir noch auf, dass die encodeWithCoder-Methode fehlt. Das ist ein Codeschnipsel aus dem Cheddar-Projekt von x02100.de. Du siehst da auch, dass die initWithCode-Methode ein wenig anders aussehen muss.

Das Ganze gehört natürlich zu der Klasse der Daten, die abgespeichert und wieder geladen werden sollen.

Code:
#pragma mark NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
	if (self = [super init])
	{
		self.title	= [decoder decodeObjectForKey:@"title"];
		self.active	= [decoder decodeBoolForKey:@"active"];
		self.sourcePaths = [decoder decodeObjectForKey:@"sourcePaths"];
		self.destinationPath = [decoder decodeObjectForKey:@"destinationPath"];
	}
	return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
	/* 
	 Diese Methode speichert die Daten des Objekts.
	 Sie wird von NSKeyedArchiver automatisch aufgerufen.
	 Man teilt in der Methode einfach mit, welche Bestandteile des Objekts man ablegen will.
	 */
	[aCoder encodeBool:self.active forKey:@"active"];
	[aCoder encodeObject:self.title forKey:@"title"];
	[aCoder encodeObject:self.sourcePaths forKey:@"sourcePaths"];
	[aCoder encodeObject:self.destinationPath forKey:@"destinationPath"];
}

Das <NSCoding> Protokoll hast du im .h-file in die Klassendefinition eingebaut?
 
Ich denke mal, das komplette Projekt wäre, wenn du überhaupt was anhängen willst, am Sinnvollsten.

Ansonsten fällt mir noch auf, dass die encodeWithCoder-Methode fehlt. Das ist ein Codeschnipsel aus dem Cheddar-Projekt von x02100.de. Du siehst da auch, dass die initWithCode-Methode ein wenig anders aussehen muss.

Das Ganze gehört natürlich zu der Klasse der Daten, die abgespeichert und wieder geladen werden sollen.

Code:
#pragma mark NSCoding
- (id)initWithCoder:(NSCoder *)decoder {
	if (self = [super init])
	{
		self.title	= [decoder decodeObjectForKey:@"title"];
		self.active	= [decoder decodeBoolForKey:@"active"];
		self.sourcePaths = [decoder decodeObjectForKey:@"sourcePaths"];
		self.destinationPath = [decoder decodeObjectForKey:@"destinationPath"];
	}
	return self;
}

- (void)encodeWithCoder:(NSCoder *)aCoder {
	/* 
	 Diese Methode speichert die Daten des Objekts.
	 Sie wird von NSKeyedArchiver automatisch aufgerufen.
	 Man teilt in der Methode einfach mit, welche Bestandteile des Objekts man ablegen will.
	 */
	[aCoder encodeBool:self.active forKey:@"active"];
	[aCoder encodeObject:self.title forKey:@"title"];
	[aCoder encodeObject:self.sourcePaths forKey:@"sourcePaths"];
	[aCoder encodeObject:self.destinationPath forKey:@"destinationPath"];
}

Das <NSCoding> Protokoll hast du im .h-file in die Klassendefinition eingebaut?

Also ich habe jetzt mal meinen gesamtes Projekt angehängt, allerdings ist es jetzt wieder wie es vorher war, da die Änderungen, die du mir vorgeschlagen hast einige Probleme verursacht hatten. Schau es dir einfach mal an.
Es speichert jetzt auch soweit die Einträge, die ich hinzugefügt habe, allerdings sollen die einzelnen Einträge auch abgehakt werden. Ich kann die einzelne Einträge auch abhaken, aber diese werden nicht gespeichert bzw. wiederholen sich nach jedem 10-ten Eintrag.
Hast du da vielleicht noch ne Idee?
 
So, ich hab mir meinen deinen Sourcecode etwas genauer angeguckt. Was mir auffällt: du speicherst in
Code:
-(IBAction)addEntry:(id)sender {
	if (!inputTextField.text)
		return;
	[inputTextField resignFirstResponder];
	[entries addObject:inputTextField.text];
	[inputTextField setText: [NSString string]];
	addButton.enabled = NO;
	[self.tableView2 reloadData];
}
ausschließlich den Textinhalt in den entries. D.h., du speicherst auch in
Code:
-(void)applicationWillTerminate:(UIApplication *)application {
	NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
	NSData *archiv = [NSKeyedArchiver archivedDataWithRootObject:tableViewController.entries];
	[defaults setObject:archiv forKey:@"entries"];
	
}
nur die Texte in den Defaults, ohne irgendwelche Markierung, ob die Felder nun abgehakt sind oder nicht.

Ich denke, du wirst um eine eigene Klasse für die abzuspeichernden Einträge nicht herumkommen.
Ich probier in der Richtung grad mal was aus.
 
So, hab mal n bisschen gebastelt. Speichern und laden funkt nun auch einschliesslich eines flags für den abgehakt-Zustand.

Edit: noch n blöden Fehler beseitigt
 

Anhänge

  • TableView.zip
    33,5 KB · Aufrufe: 59
Zuletzt bearbeitet:
Ich danke dir für deine Antwort und für das überarbeiten meines Projekts.
Das speichern funktioniert prima, aber mir ist aufgefallen, dass das abhaken nicht richtig funktioniert. Und zwar ist immer noch das Problem das es sich nach jedem 10-ten Eintrag wiederholt bzw. wenn ich "scrolle" werden bei einigen unabgehakten Zeilen dann Haken angezeigt. Hast du dafür vielleicht auch ne Idee??
Und noch ne Frage, warum war es falsch die initWithCoder-Methode zu verwenden?

Schöne Grüße
 
Hmm... ich hab nicht soviele Testeinträge gemacht, dass mir das Problem mit den Wiederholungen etc. aufgefallen wäre. Guck ich mir bei Gelegenheit aber nochmal an.

Die initWithCoder-Methode muss für die wirklich abgespeicherten Daten aufgerufen werden, nicht für den View, der die Daten anzeigt oder den Controller (Trennung Model/View/Controller, wenn dir das was sagt). Ich hab ja extra ne neue Klasse für die zu speichernden Daten eingeführt, also gehört das Handling (init jeder Art, speichern etc.) auch in Methoden für diese Klasse.
 
Hi, ich habe zwar noch immer nicht herausgefunden, warum die Haken wiederholt werden, aber ich arbeite noch daran.

Jetzt habe ich noch ein neues Problem, und zwar will ich, wenn ich auf eine Zeile des TableView klicke zu einen anderen View wechseln. Das View ist ein UIWebView, es wird auch angezeigt, es soll aber einen Text aus einer Datei anzeigen, was aber leider nicht funktioniert. Woran könnte das liegen?
Ist ein UIWebView überhaupt dazu geeignet, um Text aus einer Datei zu lesen?

Hier ist mal der Code, um auf das andere View zu wechseln:

Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	
	UIViewController *vc = [[UIViewController alloc]init];
	vc.view = [[[UIView	alloc]initWithFrame:[UIScreen mainScreen].applicationFrame]autorelease];
	
	UIWebView *webView = [[UIWebView alloc]initWithFrame:[UIScreen mainScreen].applicationFrame];
	NSString *details = [[arrayIndex objectAtIndex:indexPath.row] objectForKey:DETAILS];
	NSString *url = [BASEURL stringByAppendingString:details];
	NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
	[webView loadRequest:request];
	webView.scalesPageToFit = YES;
	[vc.view addSubview:[webView autorelease]];
	vc.title = [[arrayIndex objectAtIndex:indexPath.row]objectForKey:TITLE];
	[self.navigationController pushViewController:vc animated:YES];
	[vc release];
	[tableView deselectRowAtIndexPath:indexPath animated:YES];

}

Schöne Grüße
 
Zurück
Oben Unten