SwiftUI Projekt Umsetzen mit CoreData und mehreren Views

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

  • SwiftUI Projekt Umsetzen mit CoreData und mehreren Views

    Hallo,

    ich beschäftige mich gerade mit SwiftUI. Ich möchte meine erste Apple-APP schreiben.
    Ich habe es geschafft mit SwiftUi meine Views so zu schreiben das diese für iOS/iPAD und macOS gut aussieht.

    Was ich nur nicht so richtig verstanden habe ist:
    1. Wie geht man richtig mit den Daten aus der Datenbank um
    2. Habe mehrere FetcheRequest drin, die einfach das Gleiche machen, einfach, weil ich im scope nicht auf das eigentliche Objekt zugreifen konnte.
    Deswegen sind meine Views nicht mehr losgelöst und beinhalten teilweise Logik, die ich gar nicht in den View haben möchte, sondern auslagern könnte.

    Mein Problem ist, das wissen wie das Funktioniert.

    Beispiel:
    Ich möchte ein FetcheRequest aus der Datenbank haben und diesen FetcheRequest jeden View bereitstellen, ohne für diesen View wieder ein FetcheRequest einbauen zu müssen. (Hab die Daten ja eigentlich schon einmal geholt).

    Quellcode

    1. @Environment(\.managedObjectContext) var moc
    2. @FetchRequest(
    3. sortDescriptors: [NSSortDescriptor(keyPath: \Todo.timestamp, ascending: true)],
    4. animation: .default)
    5. private var todoItems: FetchedResults<Todo>
    6. @State var title = ""
    7. @State private var showingAlert = false
    in Todo habe ich ja mein Fetch drin und diesen möchte ich sozusagen in jedem View zugreifen können.

    Aus diesem Anlass habe ich mein Projekt nochmal übers Board geworfen und möchte nochmal von vorn Beginnen!

    Aus den Erfahrungen, die ich bisher durch meinen Selbstversuch App gesammelt habe, sind folgende Fragen aufgekommen auf die ich keine wirkliche Antwort gefunden habe.

    1. Wie kann ich ein FetchRequest so deklarieren, dass ich in jeden View darauf zugreifen kann, wo ich ihn brauche?
    2. Kann man eine View in SwiftUI so beschreiben, das keinerlei Programmlogik enthält?
    3. Wiederkehrende Funktionen losgelöst vom View das man diese im jedem View genutzt werden kann.
    4. Wie geht ihr an eure Projekte ran? Erst View beschreiben und dann Datenbank anbinden?


    Für den Anfang möchte ich es, um ein Verständnis dafür zu entwickeln, die App einfach halten.
    • Ein View der eine Liste von Elemente enthält (NavigationView mit NavigationLink)
    • Eine View die dann die Daten bekommt und die Details anzeigt. Allerdings möchte ich in dieser View auch schon Editieren können. Deswegen nicht nur Werte übergeben, was ich darstellen möchte, sondern auch Zugriff auf die Datenbank erhalten.
      Würde ich ein String für den Title und andere Werte übergeben, dann hätte ich ja keine Möglichkeit diesen Anzupassen und zu Speichern und die View wäre statisch.
    Ich bin über jeden Ratschlag, Tipp, Tutorial, Erklärung dankbar, wie man am besten an so einer App ran geht.

    Vielen Dank im Voraus!

    Gruß
    Knasan

    [Edit]:
    Punkte 1 bis 3 konnte ich selbst lösen bzw. für mich beantworten.
    Punkt 4 würde mich noch Interessieren wie ihr an eure Projekte rangeht.
    Also View für View bauen ohne Daten!? Dann das Datenmodel beschreiben und den Views integrieren mit FetchResults und Übergabe Parametern usw.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von knasan ()

  • Du hast ja Fragen für ein paar ganze Bücher :)

    Fangen wir mal klein an, du brauchst gar keinen fetchRequest in einer View. Stattdessen machst Du das in einen Object. Hier kannst Du dann auch Problemlos die Daten manipulieren und für die View veredeln. Im Prinzip gibt es zwei Arten von Objekten, diejenigen die du hast und diejenigen, welche du dir leihst. Das heisst, entweder erstellst du sie dir private oder shared du sie, via EnvironmentOjbect, Bindung, etc.

    Du solltest auch keine Logik in der View selbst haben, sondern diese kommen vom Model (Apple Sprachgebrauch). Das heisst, die View reagiert nur auf das, was das Model sagt oder sie gibt dem Model Anweisungen. Damit kannst Du die Logik zentralisieren und musst nicht wegen jeder Kleinigkeit deine Logik in zig Views nachziehen. Du musst das also entkoppeln.

    Daneben solltest du CoreData von den Model noch entkoppeln, sonst, funkt dir ständig da die Buffern dazwischen. Das haben die Apple Jünger schön gemacht, wegen der Performance, doch bekommst du deine Daten nicht immer überall aktualisiert. Das war zu früheren Zeiten besser, wo man noch einen Knopf "Neu laden" oder "Aktualisieren" anbrachte. Ist halt jetzt eine ziemliche Friemelei, wenn man mehreren Views unterwegs ist. Im Notfall dann halt entsprechende Nachrichten senden.

    Für 4: da gibt es keine richtige oder falsche Herangehensweise. mal so, mal so, ma einen mix dazwischen...
  • Wolf schrieb:

    Du hast ja Fragen für ein paar ganze Bücher
    Ja, da gebe ich Dir recht. Mit jedem Neuanfang meines Projektes ;) kommen auch immer neue Fragen hinzu. Habe zwar drei Bücher über Swift und ein Einsteiger SwiftUI gekauft und auch die Projekte so gut es ging durchgearbeitet. Aber das Problem ist, das es so viele Änderungen gab, das nicht mehr alle Projekte funktionieren. Aber diese Bücher decken leider nur einen kleinen Teil ab, wenn Du also ein Gutes-Buch kennst immer her damit.

    Das meiste habe ich aus Tutorials usw. Das Problem hierbei ist jedoch. Tutorial sind klein und erklären ein bisschen was und packen zum Verständnis alles in den ContentView usw. ist man Neu und weiß noch nicht wie der Hase läuft, dann baut man sich eine App mit sehr vielen Fehler. Deswegen wäre ein Buch oder ein Tutorial wie man eine saubere App mit CoreData schreibt wirklich eine sehr gute Sache. Wüsste sonst nicht wie ich an die Informationen kommen soll.

    Oder gibt es eine Art Guideline von Apple?
  • Das CD Tutorial von wenderlich ist nicht schlecht, bezieht sich aber rein auf UIKit. Hier geht es um SwiftUI. Das ist eine andere Baustelle.

    Hier ist zu sagen, in der View, wenn es rein nur um die Darstellung einer Tabelle geht, ist gegen den FetchRequest nichts zu sagen. Der hat sogar verschiedene Vorteile, wie dass er auf Änderungen der Datenbasis reagiert und auch nur die Daten selektiert welche gerade angezeigt werden sollen.

    Selbst hab ich mit verschiedenen Schichten ganz gute Erfahrungen gemacht, wobei die Aktualisierung über verschiedene Views mit Bezug auf dem Hauptspeicher die Herausforderung darstellt.
    Eine Logik gehört allerdings in keine View. Diese ist zu Kapseln, in einen ViewController. Dieser stellt die Logik für die View bereit und veranlasst die View bei Änderungen der Daten sich entsprechend darzustellen. Dies kann man bspw als ObservedObject realisieren. Diese Schicht ist abhängig von der View und den verwendeten Framework, ggf. von der zugrundeliegenden Hardware. Sie steuert einfach nur die View.

    Dann gibt es eine Logik Schicht, diese ist unabhängig vom Viewcontroller und sorgt einfach dafür, dass die Programmlokik korrekt ist, unabhängig vom Betriebssystem, der UI Darstellung oder der Persistenceschicht. Disee versorgt den ViewController mit verlässlichen Informationen und Daten. Dise ist unabhängig von den UI-Framework, UI-Contollern und der Persistentierung. Die verbindung zu den UI Controllern, kann man bspw via Delegates vornehmen, welche die UI Controller entsprechend informieren, wenn sich etwas ändert.

    Die Persistenceschicht, ist dann dafür verantwortlich, die Daten zu verwalten. Dies ist Dann unabhängig von der Art und weise, wie diese Persistentiert wird. Diese wird nur von der Logik Schicht aufgerufen, nie von einer View noch von einem View Controller.

    Die nächste Schicht, ist die der physikalischen Datenspeicherung. Sie hat nur Verbindung zur Persistenceschicht. Das heisst auch, allen Schichten, über der Persistenceschicht ist es vollkommen egal wie die Daten gespeichert werden. Hier werden die Tabellen definiert oder das CSV oder was sonst noch kommt.

    Der Ganze Stack funktioniert recht gut, wenn es sich nicht um zu viele Daten handelt. Denn dann muss man in Paketen abliefern und damit kommt dann bspw die Ausnahme des FetchRequests in der View wieder zu tragen.

    Wenn auch nicht zu viele Daten hast, kannst du die Logik Schicht als Environment Objekt einbinden, als zentralen Punkt, wo die Daten abgerufen und aktualisiert werden. Auf diese Daten kann dann jederzeit der Viewcontroller zugreifen und an die jeweilige View weitereichen. Ein Anlegen, Ändern oder löschen an der Persostenceschicht vorbei würde ich aber auf alle Fälle vermeiden.

    Wolf