Wie kann ich einen NSFechtResultController mit zwei section erstellen?

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

  • Wie kann ich einen NSFechtResultController mit zwei section erstellen?

    Hallo,

    ich versuche gerade einen TableView mit zwei section zustellen und diesen dann dynamisch mit CoreData zu befüllen. Das geht auch sehr gut, solange ich nur einen section habe. Jetzt frage ich mich gerade wie ich einen NSFetchResultController (FRC) erstellen bei dem ich zwei section habe, um sauber den TableView befüllen und bearbeiten kann?

    Ich habe hin bekommen den TableView mit zwei FRC's zu befüllen, aber dann bekomme ich beim hinzufügen von Datensätzen immer ein Problem mit [ending uptades], da die UI sagt es gibt zwei sections aber der FRC nur einen hat.

    Danke

    Gruß

    bongartz
    Vielen Dank

    Gruß

    Bongartz
  • So habe jetzt noch was weiter gesucht und raus gefunden wie man einen sectionNameKeyPath erzeugt, nur leider darf man hier keine many-to relationshops angeben. Leider ist das genau der Fall bei mir und ich stehe bei meinem Problem wieder am Anfang.

    Ich bekomme immer folgenden Fehlern, wenn ich ein Objekt hinzufügen will, da ich den TableView mit zwei FRC befülle.

    Quellcode

    1. ​2014-11-14 22:10:34.939 iTravel[18129:1370866] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-3318.16.14/UITableView.m:1566
    2. 2014-11-14 22:10:34.940 iTravel[18129:1370866] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (2) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted). with userInfo (null)


    Ich bin gerade etwas ratlos wie ich das Problem lösen kann.

    Danke
    Vielen Dank

    Gruß

    Bongartz
  • Ich habe die UI zu erst nur mit einer Section gehabt und dachte das die Benutzerfreundlichkeit mit zwei Sections besser wird. Somit habe ich die UI geändert.

    Wie gesagt das befallen ist ja auch kein großes Problem, hier der Code wie ich die zwei FRC erstelle:

    Quellcode

    1. ​-(void)viewDidLoad {
    2. [super viewDidLoad];
    3. if (self.event != nil) {
    4. NSPredicate* suchePersonPayed = [NSPredicate predicateWithFormat:@"ANY %K == %@", cEntityPersonRelationshipEvent, self.event];
    5. NSPredicate* sucheKostenPayed = [NSPredicate predicateWithFormat:@"ANY kosten.wertBezahlt != 0"];
    6. self.basePredicatePayed = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: suchePersonPayed, nil]];
    7. self.fetchPredicatePayed = self.basePredicatePayed;
    8. NSPredicate* suchePersonDontPayed = [NSPredicate predicateWithFormat:@"ANY %K == %@", cEntityPersonRelationshipEvent, self.event];
    9. NSPredicate* sucheKostenDontPayed = [NSPredicate predicateWithFormat:@"ANY kosten.wertBezahlt == 0"];
    10. self.basePredicateDontPayed = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects: suchePersonDontPayed, sucheKostenDontPayed, nil]];
    11. self.fetchPredicateDontPayed = self.basePredicateDontPayed;
    12. } else {
    13. self.fetchPredicatePayed = nil;
    14. self.basePredicateDontPayed = nil;
    15. }
    16. [JSMCoreDataHelper performOnFetchResultController:self.fetchedResultsController];
    17. [JSMCoreDataHelper performOnFetchResultController:self.fetchedResultsControllerDontPayed];
    18. }
    Alles anzeigen


    Wie man sehen kann teile ich die Section auf, ob jemand etwas bezahlt hat oder nicht. Nur da eine Personen mehrere Kosten haben kann und muss, geht es so nicht mit den sectionNameKeyPath.

    Anbei noch ein Bild meines Models.

    [Blockierte Grafik: http://bilder.bitsmaker.de/Xcode.jpg]

    Danke

    Gruß

    Bongartz
    Vielen Dank

    Gruß

    Bongartz
  • Oh ok, macht Sinn. Ich habe ein ähnliches Problem in einer App so gelöst:

    In der Subclass zum NSManagedObject ein Property hinzugefügt nach welchem ich gruppieren möchte. In Deinem Fall sollte dieses Property den Zustand bezahlt oder nicht ausdrücken. In der Implementierung erstellst Du für dieses Property dann einen Getter, welcher den aktuellen Zustand für bezahlt oder nicht ermittelt.

    In dem NSFetchedResultsController kannst Du dieses Property dann als sectionNameKeyPath verwenden.

    Ich tippe jetzt einfach mal, dass Du den Zustand bezahlt oder nicht bezahlt nicht nur für die Gruppierung/Teilung der Anzeige benötigst, sondern evtl. auch in der Detail Ansicht, richtig? Hast Du den Zustand an den benötigten Stellen dann immer über einen eigenen FetchRequest ermittelt?
  • Ok, ich hatte sowas versucht bei der Subklasse "Kosten" hier habe ich "Type" als Integer hinzugefügt, da ich aber Personen anzeige, konnte ich diesen weg über den sectionNameKeyPath nicht gehen, da many-to Relationships.

    Ich bin mir gerade nicht ganz sicher welche Klasse du meinst wo ich das ohne many-to Relationship hinzufügen kann?

    Danke
    Vielen Dank

    Gruß

    Bongartz
  • Mir ist jetzt die Idee gekommen. Einfach den FRC über die Enitiy "Kosten" aufzubauen, da ich ja hier zugriff auf alle anderen Entitys habe :)

    Jetzt habe ich nur noch ein Problem. Meine UI sieht es vor, das ich immer zwei Section im TableView aufbaue, da über die SectionsHedaer meine Inhalte hinzugefügt werden. Wenn jetzt natürlich keine Daten für Section zwei vorliegen gibt es diesen noch nicht im FRC. Gibt es einen weg folgenden Ausdruck zu prüfen ob dieser != Nil ist?

    Ich erzeuge per Hand immer zwei Sections, somit tritt dieser Fehler natürlich erst auf.

    Quellcode

    1. ​[[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects


    Danke
    Vielen Dank

    Gruß

    Bongartz
  • So habe das Problem jetzt etwas anders gelöst, da ich ja die Anzahl der Sections kennen.

    Danke für die Hilfe und den Denkanstoß :)

    Quellcode

    1. ​if (section == 0 || (section == 1 && [self.fetchedResultsController sections].count == 2)) {
    2. return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
    3. } else {
    4. return 0;
    5. }
    Vielen Dank

    Gruß

    Bongartz
  • So jetzt habe ich alles so erstellt, das ich mit meinem sectionNameKeyPAth arbeiten kann und wenn ich jetzt Daten in CoreData ablegen will kommt dieser tolle neue Fehler :(

    [code]2014-11-15 12:30:45.920 iTravel[19371:1558420] CoreData: error: Serious application error. Exception was caught during Core Data change processing. This is usually a bug within an observer of NSManagedObjectContextObjectsDidChangeNotification. The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet. with userInfo (null)

    2014-11-15 12:30:45.934 iTravel[19371:1558420] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'The left hand side for an ALL or ANY operator must be either an NSArray or an NSSet.'


    Vielen Dank

    Gruß

    Bongartz

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Bongartz ()

  • Die ganzen 205 Zeilen möchte ich mir gerade nicht antun, aber ich bin ziemlich sicher, dass es deutlich kürzer geht:
    Man muss ja nicht einen FetchedResultsController benutzen - es geht auch ohne, oder mit zweien...

    Bongartz schrieb:

    for (NSNumber* i = [NSNumber numberWithLong:1]; i.longValue <= [[self fetchedResultsController] fetchedObjects].count; i = [NSNumber numberWithLong:i.longValue + 1]){

    Manöverkritik: Viel zu lang - selbst wenn du i in der Schleife brauchst, ist es effektiver einen ganz langweiligen Integer-Datentyp (int, wenn man wenig tippen will, unsigned long, wenn man Angst hat, dass die Schleife richtig lange läuft ;) zu verwenden.
  • Ja habe das Problem auch gelöst. Hatte noch bei einer Abfrage ANY drin musste dies natürlich löschen da ich kein to-Many mehr hatte.

    Zu der Schleife, ich hatte das vorher mit int, aber durch 64 Bit war ich mir nicht mehr sicher ob ich das so lassen kann und habe es dann über NSNumber löst.

    Wäre es mit Int_64 auch 64 Bit und 32 bit sicher?
    Vielen Dank

    Gruß

    Bongartz
  • Bongartz schrieb:

    Wäre es mit Int_64 auch 64 Bit und 32 bit sicher?


    Auch auf die Gefahr hin, mich jetzt etwas zu weit aus dem Fenster zu lehnen: Ja, natürlich.
    "sicher" kann ja vieles bedeuten - aber mir fällt kein Nachteil, den man an der Stelle mit NSNumber umschiffen könnte; und solange man nicht anfängt, Daten an andere Systeme zu übertragen muss man sich höchstens Sorgen machen, dass es einen Überlauf gibt (aber dafür muss man sich sogar bei 16-Bit Zahlen schon ordentlich ins Zeug legen)
  • Ich habe nur gelesen das man bei int_64 auf passen muss, da es auf 32 Bit system 8 Bit hat und auf 64 Bit 16 bit hat. Wobei das bei mir eigentlich egal seinen sollte, da ich ja nie so große Objekte bekomme.

    Ich habe jetzt aber zu meiner Frage von oben noch ein Problem bekommen. Ich sage ja meinem TableViewController das er 2 Section hat, auch wenn der FRC nur eine hat, damit meine UI geht. Jetzt stehe ich vor dem Problem, wenn ich einen leeren Controller habe und das erste mal in section zwei was anlegen will, mir Xcode sagt, das es nicht geht da ich vorher schon zwei section hatte und eine hinzugefügt wird und es dann immer noch zwei section sind.

    Quellcode

    1. ​2014-11-15 21:30:31.941 iTravel[21224:1733630] CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of sections. The number of sections contained in the table view after the update (2) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted). with userInfo (null)


    Jetzt meine Frage, kann ich dem FRC aufzwingen, dass er auch die zweite section erstellt auch wenn diese 0 Rowe hat? Oder kann man die HeaderSection immer anzeigen, sich wenn der TableView nur eine section hat?
    Vielen Dank

    Gruß

    Bongartz
  • Puh,

    also langsam verliere ich wirklich meine Lust bei diesem FRC. Ja wie gesagt das darstellen geht eigentlich auch, nur das hinzufügen eines neuen Objektes geht halt nicht, weil dann der TableViewController diesen sinnlosen Fehler verursacht. Zu dem habe ich noch einen Fehler hinzubekommen mit diesem tollen FRC :-(.

    Vielleicht hast du ja Lust das Projekt als Git zu laden damit du siehst was mein Problem ist.
    Vielen Dank

    Gruß

    Bongartz