Problem mit hübschen Schauspielerinnen - Teil 1 | [iOS, Swift, CoreData, Update, Relationship, one-to-many]

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

Macoun 2019 - Frühbucherrabatt bis 26.7.2019

  • Problem mit hübschen Schauspielerinnen - Teil 1 | [iOS, Swift, CoreData, Update, Relationship, one-to-many]

    # Problem mit hübschen Schauspielerinnen - Teil 1 | [iOS, Swift, CoreData, Update, Relationship, one-to-many]

    Hallo liebe Community … okay ich gebe es zu ich wollte mit dem Titel die nötige Aufmerksamkeit erreichen (sex sells). Daher hier ein etwas gefaktes Beispiel meines eigentlichen Problems, aber das Problem als solches ist leider echt.

    ## [tltr]
    Hauptfragestellung: Ich weiß, wie ich Daten in eine CoreData Relationship 1:n Beziehung anlegen. Aber wie ändere ich die Daten dazu ab?

    ## [was will ich erreichen / was klappt bis lang]
    Gehen wir einmal davon aus, dass ich eine App schreiben möchte, in der ich hübsche Schauspielerin (1. Entity „Actress“) anlegen kann. Und ich für diese Schauspielerin ihren täglichen Workoutplan (2. Entity „Workouts“) anlege. Um es nicht zu kompliziert zu machen: nur 1 Workout pro Tag möglich.

    .. bla bla ..

    Ich habe also irgendwo einen EditActressViewController. Hier möchte ich sowohl neue als auch geänderte Schauspielerinnen anlegen/updaten. In dem EditActressViewController gibt es sowohl die Möglichkeit die Stammdaten (Name und so) zu speichern als auch die Workout-Tagen (denkt daran nur 1/Tag).

    Das neue bzw. erstmalige Speichern sowohl der Stammdaten (Entity Actress) als auch der „Bewegungsdaten“ (Entity Workouts).

    hier mal der ..
    ## [code dazu]

    C-Quellcode

    1. // FIXME: Pseudo-Code *rofl*
    2. // save-Funktion innerhalb des EditActressViewControllers
    3. // zum Editieren als auch erstmaligem Abspeichern
    4. @IBAction func saveData(sender: UIBarButtonItem) {
    5. // --- what shall we do with the drunken sailor
    6. // Unterscheide zwischen neuem Datensatz (newActress) und altem (die 'Else')
    7. var myActressObject: Actress // CoreData - Entity
    8. // --> neu anlegen
    9. if modus == "newActress" {
    10. myActressObject = NSEntityDescription.insertNewObjectForEntityForName("Actress", inManagedObjectContext: self.moc) as! Actress
    11. }
    12. // --> edit
    13. else {
    14. myActressObject = handOverActressObject
    15. }
    16. // --- Stammdaten
    17. // Actress-Objekt Befüllung aus TextFields übernehmen / Entity 'Actress'
    18. myActressObject.name = tfName.text // "z.B. Katie Holmes"
    19. myActressObject.city = tfCity.text // "z.B. New York"
    20. // --- "Bewegungsdaten"
    21. // Workouts-Objekte Befüllung aus TextFields übernehmen / Entity 'Workouts'
    22. // set definieren
    23. var workOutSets: Set<Workouts> = Set<Workouts>()
    24. // wo soll der ganze Krams rein, wenn gefüllt
    25. // .. für Sonntag
    26. if checkIfDayIsNotEmpty(tfStart1, time2: tfStopp1) {
    27. let workOutDay = NSEntityDescription.insertNewObjectForEntityForName("Workouts", inManagedObjectContext: self.moc) as! Workouts
    28. workOutDay.weekOfDay = 1
    29. workOutDay.title = tfTitle1.text // z.B. "Jogging with Suri"
    30. workOutDay.start = tfStart1.text // z.B. "10:00"
    31. workOutDay.stopp = tfStopp1.text // z.B. "10:01"
    32. workOutSets.insert(workOutDay)
    33. }
    34. // .. für Montag
    35. if checkIfDayIsNotEmpty(tfStart2, time2: tfStopp2) {
    36. let workOutDay = NSEntityDescription.insertNewObjectForEntityForName("Workouts", inManagedObjectContext: self.moc) as! Workouts
    37. // Sonntag
    38. workOutDay.weekOfDay = 2
    39. workOutDay.title = tfTitle1.text // z.B. "Instructions with this app developer"
    40. workOutDay.start = tfStart2.text // z.B. "22:00"
    41. workOutDay.stopp = tfStopp2.text // z.B. "23:42"
    42. workOutSets.insert(workOutDay)
    43. }
    44. // ...
    45. myActressObject.relationship2Workouts = NSSet(set: workOutSets)
    46. // --- Speichern
    47. // .. hier nur die Kurzversion ;-)
    48. try! myActressObject.managedObjectContext?.save()
    49. }
    Alles anzeigen



    ## [was ist mein Problem]
    Für die Entity „Actress“ macht mein Code oben ja bereits eine saubere Unterscheidung zwischen „neu anlegen“ und „edit“. Bei dem Update der Workouts fehlt mir gerade jegliche Phantasie, was ich hier machen soll.
    siehe oben [tltr]


    ## [was ich bereits probiert habe]
    mit FetchRequest auszulesen, welche Workouts es gibt. Okay, aber was gebe ich für einen predicate an? CoreData ist ja keine Datenbank und ich hätte keinen echten Primärschlüssel im Zugriff. Klar kann ich wenigstens mit predicate auf ‚weekOfDay‘ sicherstellen, dass ich den richtigen Tag abändere.
    Oder muss ich tatsächlich

    ## [Randgruppeninfos]
    Vielleicht ist es ja wichtig, wie das Datenmodell aussieht? Muss ich evtl. einen eigenen Primärschlüssel mitangeben (aber dann wäre ich ja langsam weit weg von CoreData und deutlich mehr an Datenbanken dran):

    Quellcode

    1. extension Actress {
    2. @NSManaged var name: String?
    3. @NSManaged var city: String?
    4. @NSManaged var relationship2Workouts: NSSet?
    5. }
    6. extension Workouts {
    7. @NSManaged var weekOfDay: NSNumber?
    8. @NSManaged var start: String?
    9. @NSManaged var stopp: String?
    10. @NSManaged var relationship2Actress: Actress?
    11. }
    Alles anzeigen

    ## [Hilfe]
    ich weiß, ich weiß: Natürlich helfen mir verbale Denkanstösse, aber ob ihr es glaubt oder nicht … ich freue mich auch echt riesig über (Pseudo-)Codezeilen.


    Ansonsten hoffe ich ihr hattet ein biste Spaß beim Lesen des Eintrags ... das wäre ja auch okay!
    Fröhliches Ostereier-Jagen
    ifeelhorst


    evtl. schöner formatiert zu sehender Quellcode

    ----
    Macht's gut und danke für den Fisch
  • Mac & i Test Abo
  • Nun, über die relationship2Workouts Property des Actress Objekts kommst du an die Workouts. Die kannst du dann bearbeiten oder löschen. Wenn du einen neuen Workout einer Actress zuordnen willst, setzt du einfach die relationship2Actress Property im Workouts (wieso eigentlich nicht Workout?) Objekt. Wenn du im Modell die Reverse Relationship gesetzt hast, fügt Core Data für dich dann den neuen Workout in das relationship2Workouts-Set ein.
  • Hallo Michael,

    danke für Deine Antwort.
    Ich hänge aber noch etwas damit. Ich will ja z.B. nur den Sonntag (ver)ändern?

    Einen "Workout.relationshop2Actress" kann ich nicht aufrufen. Wahrscheinlich weiß ich nur nicht, wie ich das machen soll. Ich könnte jetzt einen FetchRequest machen und das an eine eigene Property übergeben, aber wie schränke ich auf den gerade zu verarbeitenden Shop ein. Gefühlt fehlt mir - um kurz in Datenbanken abzuspringen - ein "UPDATE ... WHERE actressID = <id>". Hab ich natürlich nicht, aber wie/woher weiß meine Property, dass ich nicht alle "weekOfDay = 1" abändern will?

    probiert hatte ich so etwas ...

    C-Quellcode

    1. var timeSets: Set<Workout> = Set<Wortkout>()
    2. let request = NSFetchRequest(entityName: Workout)
    3. request.predicate = NSPredicate(format: "weekOfDay == %", 1)
    4. let workOutObjects = try! self.moc.executeFetchRequest(request) as! [Workout]
    aber was mach ich jetzt mit dem 'workOutObjects'. Da ist dann ja auch alles drin ... nicht nur für Katie ... äh ... die eine eben noch bearbeite Schauspielerin.
    ----
    Macht's gut und danke für den Fisch
  • Die zu bearbeitende Person (Actress) hast du doch schon, oder? Dann brauchst du nichts mehr fetchen:

    Quellcode

    1. var timeSets: Set<Workout> = actress.relationship2Workouts

    Das filterst du dann einfach noch nach dem gewünschten Wochentag:

    Quellcode

    1. let day = 2
    2. let filteredSet = timeSets?.filter { wo -> Bool in
    3. return wo.weekOfDay == day
    4. }
    Damit hast du dann den gewünschten Wochentag (noch in Optionals und Set verpackt, Swift halt).