TableView zeigt keine Daten an(CoreData) - Absturz

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • TableView zeigt keine Daten an(CoreData) - Absturz

    Hallo Leute,

    ich bekomme meine Daten aus der Datenbank nicht ausgelesen.
    Ich hab eine App mit einem TabBarController. Im ersten Tab wird mit der iPhone-Kamera ein Barcode gescannt und dieser an ein View(CameraReturnDetailViewController) weitergegeben.
    Im CameraReturnDetailViewController-View befindet sich der Speichern-Button mit folgendem Code:


    CameraReturnDetailViewController.m

    Quellcode

    1. - (IBAction)saveAndQuitScan:(id) sender {
    2. XLog(@"saveAndQuitScan button wurde geklickt!");
    3. ProjectQRCodeAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    4. NSManagedObjectContext *context = [appDelegate managedObjectContext];
    5. NSManagedObject *newData;
    6. newData = [NSEntityDescription insertNewObjectForEntityForName:@"BarcodeDaten" inManagedObjectContext:context];
    7. [newData setValue:dataLabel.text forKey:@"Barcode_CD"];
    8. NSError *error;
    9. [context save:&error];
    10. //Aktuelle ansicht (self) animiert verlassen
    11. [self dismissModalViewControllerAnimated:YES];
    12. // Nachdem die ansicht verlassen wurde,
    13. // auf das zweite Tab wechseln(scanverlauf)
    14. /** TO DO - Funktioniert noch nicht **/
    15. [self.tabBarController setSelectedIndex:1];
    16. }
    Alles anzeigen



    Jetzt möchte ich meine Daten in einem anderen View (ScansViewController) in eine TableView laden.

    ScansViewController.m

    Quellcode

    1. - (void)viewDidLoad {
    2. [super viewDidLoad];
    3. if (managedObjectContext_ == nil)
    4. {
    5. managedObjectContext_ = [(ProjectQRCodeAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    6. NSLog(@"After managedObjectContext: %@", managedObjectContext_);
    7. }
    8. myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame] style:UITableViewStylePlain];
    9. myTableView.delegate = self;
    10. myTableView.dataSource = self;
    11. myTableView.autoresizesSubviews = YES;
    12. self.navigationItem.title = @"Code Liste";
    13. self.view = myTableView;
    14. }
    15. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    16. return [itemsList count];
    17. }
    18. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    19. static NSString *CellIdentifier = @"Cell";
    20. UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    21. if (cell == nil) {
    22. cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    23. }
    24. return cell;
    25. }
    26. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    27. return 1;
    28. }
    29. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    30. NSString *selectDay = [NSString stringWithFormat:@"%d", indexPath.row];
    31. TableDetailViewController *fvController = [[TableDetailViewController alloc] initWithNibName:@"TableDetailViewController" bundle:[NSBundle mainBundle]];
    32. fvController.selectDay = selectDay;
    33. [self.navigationController pushViewController:fvController animated:YES];
    34. [fvController release];
    35. fvController = nil;
    36. }
    37. - (void) configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    38. NSManagedObject *managedObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
    39. cell.textLabel.text = [[managedObject valueForKey:@"Barcode_CD"] description];
    40. }
    41. - (NSFetchedResultsController *) fetchedResultsController {
    42. if (fetchedResultsController_ !=nil) {
    43. return fetchedResultsController_;
    44. }
    45. NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    46. NSEntityDescription *entity = [NSEntityDescription entityForName:@"BarcodeDaten" inManagedObjectContext:self.managedObjectContext];
    47. [fetchRequest setEntity:entity];
    48. [fetchRequest setFetchBatchSize:20];
    49. NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Barcode_CD" ascending:NO];
    50. NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    51. [fetchRequest setSortDescriptors:sortDescriptors];
    52. NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
    53. aFetchedResultsController.delegate = self;
    54. self.fetchedResultsController = aFetchedResultsController;
    55. [aFetchedResultsController release];
    56. [fetchRequest release];
    57. [sortDescriptor release];
    58. [sortDescriptors release];
    59. NSError *error = nil;
    60. if (![fetchedResultsController_ performFetch:&error]) {
    61. XLog(@"Error: %@, %@", error, [error userInfo]);
    62. abort();
    63. }
    64. return fetchedResultsController_;
    65. }
    Alles anzeigen



    Erst bekam ich einen Absturz mit dieser Fehlermeldung:

    "
    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'BarcodeDaten''
    "


    Obwohl der Name richtig ist, wundert mich diese Fehlermeldung. Den absturz konnte ich mit der oben im Code fett markierten zeilen unterdrücken.




    Doch warum kann ich die Daten nicht in die Tabelle laden? Was habe ich falsch gemacht?


    Gruß und danke für jegliche Hilfe,
    brush51

  • Das ist richtig, ja.
    Hast du nachträlich das xcdatamodel bearbeitet?
    Wenn ja, hast du wohl gerade das gleiche Problem, was ich auch immer Anfangs auch hatte und falsch machte...

    Du musst von dem aktuellen xcdatamodel erst eine neue Version anlegen. Das machst du, in dem du die Datei *.xcdatamodel in Xcode markierst, anschließend über [Menü -> Design -> Date Model -> Add Model Version]
    Anschließend bearbeitest du im neuen Modell deine Entitäten etc.
    Wenn du fertig bist, setzt du über den selben Weg, nur "Set Current Version" statt "Add Model Version".
    Diese Schritte sind wichtig, damit Änderungen auch in der Datenbank am Gerät durchgeführt werden.

    Anschließend müsste sich die neue Version starten lassen.

    Was bei mir auch schon öfters geholfen hat ist, die Anwendung vom Simulator zu entfernen oder auch einfach mal "Clean All" beim "Build" zu wählen.

    Hoffe ich konnte etwas helfen.

    Gruß,
    Tobi
  • Kronos schrieb:

    Das ist richtig, ja.
    Hast du nachträlich das xcdatamodel bearbeitet?
    Wenn ja, hast du wohl gerade das gleiche Problem, was ich auch immer Anfangs auch hatte und falsch machte...

    Du musst von dem aktuellen xcdatamodel erst eine neue Version anlegen. Das machst du, in dem du die Datei *.xcdatamodel in Xcode markierst, anschließend über [Menü -> Design -> Date Model -> Add Model Version]
    Anschließend bearbeitest du im neuen Modell deine Entitäten etc.
    Wenn du fertig bist, setzt du über den selben Weg, nur "Set Current Version" statt "Add Model Version".
    Diese Schritte sind wichtig, damit Änderungen auch in der Datenbank am Gerät durchgeführt werden.

    Anschließend müsste sich die neue Version starten lassen.

    Was bei mir auch schon öfters geholfen hat ist, die Anwendung vom Simulator zu entfernen oder auch einfach mal "Clean All" beim "Build" zu wählen.

    Hoffe ich konnte etwas helfen.

    Gruß,
    Tobi
    Nein geändert habe ich nichts an der Datenbank aber ic führ das dennoch einmal durch. Ich lösche immer die App vorher bevor ichs neu compiliere.
    Ich hab jetzt angefangen es von neu zu programmieren, um mögliche Fehlerquellen auszuschliessen und es auch besser zu verstehen wie das funktioniert.

    Hier meine bisher durchgeführten Schritte:

    - Neues Projekt angelegt (window based application) und den haken bei Use CoreData for storage gewählt.
    - Zuerst neue UIView Subclasses mit XIB Dateien erstellen (einmal ScanQRViewController, einmal ScanHistoryViewController->Als TableView ausgewählt )
    - IBOutlets in der ScanQRViewController angelegt
    - Buttons und Textfelder usw mit IB im ScanQRViewController.xib angelegt und verbunden
    - ProjectNameAppDelegate hab ich UITabBarController definiert und als subview hinzugefügt
    - MainWindow.xib geöffnet, einen TabbarController hinzugefügt und verbunden

    - App gestartet, alles geht, kein Absturz

    - ScanQRViewController IBActions hinzugefügt (für die Buttons um kamera zu öffnen)
    - ZBarSDk implementiert, ausgaben getestet, funktioniert alles.

    - ProjectName.xcdatamodel geöffnet und eine neue Entity namens "Event" mit zwei attributen (barCode, timeStamp beide als String) angelegt
    und dann die Managed Object Class generiert.

    Sooo bis hierhin alles korrekt?
    Was kommt als nächstes? Warte ich antworte: SpeichernButton mit weiterem Code beschmücken. Jetzt muss ich das erst mal machen aber tipps diesbezüglich nehme ich gerne an :)

    danke,
    brush51
  • Das ist jetzt mein saveButton:

    Quellcode

    1. - (IBAction) saveScannedQRCode:(id) sender {
    2. NSLog(@"saveScannedQRCode entered");
    3. QRCodeAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    4. NSManagedObjectContext *context = [appDelegate managedObjectContext];
    5. NSManagedObject *newData;
    6. newData = [NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
    7. [newData setValue:dataTF.text forKey:@"barCode"];
    8. [newData setValue:timeStampTF.text forKey:@"timeStamp"];
    9. NSError *error;
    10. [context save:&error];
    11. NSLog(@"erroroutput: %@", error);
    12. }
    Alles anzeigen


    Beim klicken des Buttons stürzt die App auf dem iPhone ab aber im Simulator nicht.

    Was mach ich denn falsch??
  • In der Datei ProjectName.xcdatamodel gibts da nicht bereits eine Entität mit dem Namen "Event"?
    War bei mir schon immer der Fall...

    Was auf ein Tipp wäre ist, die Anwendung nicht als WindowBased, sondern mit einem TableViewController und CoreData zu erstellen. Da du das ja sowieso verwenden möchtest, richtig? Das spart dir einiges an Arbeit...
    (Du kannst nachträglich dann ein TabBar inkl. einem anderen View als ersten sichtbaren erstellen.)
    Es gibt dann auch bereits einen "Speichern"-Button. Da könntest du dir das meiste abguckn.
    Aber wie gesagt, bei JEDER änderung am xcdatamodel, immer zuerst eine neue Version erstellen und diese dann nach den Änderungen als Standard setzen.

    Welche Fehlermeldung bekommst du in der Konsole wenn du die App am iPhone startest? (im Organizer gibts dazu ne Konsole)

    Gruß,
    Tobi
  • Kronos schrieb:

    In der Datei ProjectName.xcdatamodel gibts da nicht bereits eine Entität mit dem Namen "Event"?
    War bei mir schon immer der Fall...

    Was auf ein Tipp wäre ist, die Anwendung nicht als WindowBased, sondern mit einem TableViewController und CoreData zu erstellen. Da du das ja sowieso verwenden möchtest, richtig? Das spart dir einiges an Arbeit...
    (Du kannst nachträglich dann ein TabBar inkl. einem anderen View als ersten sichtbaren erstellen.)
    Es gibt dann auch bereits einen "Speichern"-Button. Da könntest du dir das meiste abguckn.
    Aber wie gesagt, bei JEDER änderung am xcdatamodel, immer zuerst eine neue Version erstellen und diese dann nach den Änderungen als Standard setzen.

    Welche Fehlermeldung bekommst du in der Konsole wenn du die App am iPhone startest? (im Organizer gibts dazu ne Konsole)

    Gruß,
    Tobi
    Danke erstmal für die Hilfe.

    Ja ich möchte schon einen tableViewController verwenden, allerdings nur für die spätere darstellung der datensätze.
    Vorerst wäre ich sehr froh wenn ich das speichern hinbekommen würde.

    Nein ein "Event" war vorher nicht drin, soweit ich weiss ist das nur beim NavigationBased Template mit dabei.

    Sind denn die zeilen die ich zum speichern habe richtig?? Kannst du mir das bestätigen?

    Vorhin kam die fehlermeldung mit error: null wenn ich auf den savebutton geklickt hatte.
  • Ich hatte anfangs auch immer die selben schwierigkeiten mit CoreData wie du auch...
    Manchmal funktionierte das nicht, manchmal das. Habe auch öfters die Anwendungen gelöscht und von neu angefangen, bis ich dann irgendwo im Internet das mit der neuen Version erzeuge von xcdatmodel fand und von da an funktionierte alles...
    Das hatte ich - leider - bis jetzt in keinem Buch gefunden...

    Soweit sehe ich keinen Fehler in deinem Code.
    Bis eben auf diese Zeile:

    Quellcode

    1. [newData setValue:timeStampTF.text forKey:@"timeStamp"];


    Ersetz das doch mal - testweise - durch das hier:

    Quellcode

    1. [newData setValue:[NSDate date] forKey:@"timeStamp"];


    Ich gehe davon aus, dass das Attribut "timeStamp" in der Datenbank kein String-Feld ist sondern Timestamp.

    Gruß,
    Tobi
  • Nein ist nicht als Date definiert, sondern als String. War schon richtig aber trotzdem danke für den Hinweis :)

    Jetzt bekomme ich folgende Fehlermeldung hab ich vorhin wohl übersehen, sorry:

    Quellcode

    1. *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'


    Ich glaube ich hab irgendetwas vergessen ...
  • Hmm, sieht fast danach aus, ja
    Das einfachste ist wirklich, eine App aus dem Template für TableView und CoreData zu erstellen. Hier gibts auch schon nen Prozess, der dir nen Datensatz speichert.
    Anhand dessen würd ich aufbauen. (machte ich auch in meinem derzeitigen Projekt) so ist es ziemlich einfach wenn man auch noch die anderen Kleinigkeit beachtet ;)

    Gruß,
    Tobi
  • Bitte immer die Upload-Funktion des Forums verwenden und vorher den build-Ordner löschen.

    Zwei Sachen habe ich gefunden:
    1. Wenn Du ein neuen Eintrag anlegst, solltest Du keinen String übergeben, wo ein Datum erwartet wird (timeStamp-Property). Verwende doch lieber einen DatePicker für die Eingabe des Datums anstatt eines Textfeldes.
    2. Die Zellen in Deinem TableView werden angezeigt. Du solltest sie nicht leer lassen, sondern ihnen etwas zuweisen; z. B.: cell.titleLabel.text = @"Bla";
    „Meine Komplikation hatte eine Komplikation.“
  • macmoonshine schrieb:

    Bitte immer die Upload-Funktion des Forums verwenden und vorher den build-Ordner löschen.

    Zwei Sachen habe ich gefunden:
    1. Wenn Du ein neuen Eintrag anlegst, solltest Du keinen String übergeben, wo ein Datum erwartet wird (timeStamp-Property). Verwende doch lieber einen DatePicker für die Eingabe des Datums anstatt eines Textfeldes.
    2. Die Zellen in Deinem TableView werden angezeigt. Du solltest sie nicht leer lassen, sondern ihnen etwas zuweisen; z. B.: cell.titleLabel.text = @"Bla";
    Ich hab den Timestamp jetzt komplett rausgenommen, mir geht es erst mal darum überhaupt Daten speichern zu können, um die Details kümmere ich mich später.
    Trotzdem danke für die Tips. Ne/n andere/r (eine) idee warum es nicht funktionieren könnte ??

    Die Zipdatei ist 1,2 MB groß, obwohl ich den build ordner gelöscht hab. Deswegen musste ichs wo anders hochladen.
  • Ich habe die App nochmal neu programmiert (nur daten speichern mit CoreData) und hinterher dann in ein TableView geladen. Dabei ist es immer abgestürzt und hab dann folgende fehlermeldung bekommen:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Event''


    Nachdem ich diese Fehlermeldung damit unterdrücken konnte funktionierte auch das einlesen der Daten:

    Quellcode

    1. if (managedObjectContext_ == nil) { managedObjectContext_ = [(QRCodeAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; NSLog(@"After managedObjectContext_: %@", managedObjectContext_); }



    Danke für die Hilfen,
    brush51