Kotlin Multiplatform Mobile und So teilen Sie ViewModel: Ein Architekturvorschlag Lähde: Federico Torres | Januar 2022

- iOS und Android: Diese Module enthalten iOS- und Android-Anwendungen (Xcode- und Android Studio-Projekte). Der Großteil des Codes sollte nur aus SwiftUI und ComposeUI bestehen.
- Kotlin teilt den Code: Dies ist ein Modul, das das KMM-Projekt enthält, hier werden wir unsere Geschäfts- und Präsentationslogik implementieren. Der Kern unserer App wird also hier sein.
- Zwiebel: Dies ist die KMM-Bibliothek, die ich erstellt habe und die wir als Abhängigkeit zu unserem gemeinsamen Code hinzufügen werden.
Bogen ist eine kleine und leichtgewichtige Kotlin-Multiplattform-Bibliothek, die uns bei der Architektur mobiler Anwendungen hilft, sie basiert auf der Spotify Mobius-Bibliothek, aber anstatt sich auf RxJava zu verlassen, verlässt sie sich auf Roots, SharedFlow ich StateFlow
Wir werden die grundlegenden Konzepte der Bibliothek wiederholen, ich werde einige Themen auslassen, wie z Veranstaltungen und Umgang mit Fehlern nur der Einfachheit halber.
Hauptmerkmale:
- Fluss in eine Richtung
- Einfache Zustandsverwaltung
- Jetpack-Unterstützung ViewModel (unter Verwendung des tatsächlichen / erwarteten Protokolls)
Anwendungsablauf mit Arch
Dieses Diagramm zeigt, wie die Komponenten in dieser Architektur interagieren, schauen wir uns jede von ihnen an und geben eine kurze Erklärung:
- Aktionen: action ist eine Anforderung, den Status der Anwendung (oder eines Teils davon) zu ändern, Aktionen werden von iOS- und Android-Code gesendet.
- Aktualisieren: Sie können sich das Update als reine Funktion vorstellen, die die Aktion und den aktuellen Zustand entgegennimmt und den neuen Zustand wiederherstellt. Neben der Änderung der Bedingung hat Updater Ich kann senden Nebenwirkungen ich Veranstaltungen
- Nebenwirkungen: Im Allgemeinen ist ein Nebeneffekt eine Operation, die einen Zustand außerhalb seiner lokalen Umgebung in unserer Architektur ändert Nebenwirkungen sind Operationen wie HTTP-Anforderungen, Datenbanktransaktionen oder beliebige I/O-Operationen.
- Prozessor: der Prozessor ist das Element, das er verarbeitet Nebenwirkungen ist für die Ausführung einer Datenbanktransaktion, einer HTTP-Anfrage oder irgendetwas Empfangenem verantwortlich Nebenwirkung solltest. Wenn die Aufgabe abgeschlossen ist (erfolgreich oder nicht), sendet der Prozessor eine neue Aktion um den Status zu aktualisieren.
Lassen Sie uns in den eigentlichen Code eintauchen, wir werden eine sehr einfache Anwendung für Filme mit dieser vorgeschlagenen Architektur schreiben film db api
Schritte
- Definiere den Zustand
- Definieren Aktionen
- Nebenwirkungen definieren
- Erstellen Sie ein Ansichtsmodell
- Implementieren Updater
- Implementieren Prozessor
- Beobachten Sie die Zustandsänderungen in den Ansichten SwiftUI und ComposeUI.
Mit Ausnahme des letzten werden alle diese Schritte in unserem gemeinsamen Valley-Modul implementiert.
Zustand
Für diese App müssen wir nur zwei Dinge in unserem Zustand speichern:
- Liste der Filme
- Ausgewählter Film, da wir die Details des Films anzeigen möchten, wenn der Benutzer ihn in der Liste berührt.
Aktionen
Wir brauchen nur drei Aktionen:
Die ersten beiden Aktionen werden an Benutzerereignisse gesendet (z. B. Berühren oder Öffnen einer App), die letzte wird gesendet Prozessor wenn wir eine Antwort von der API erhalten.
Nebenwirkungen
Wir haben eine Single Nebenwirkung: Holen Sie sich eine Liste von Filmen. Wir könnten festlegen, auf welcher Reihe von Dispatchern oder Cornets wir laufen möchten Nebenwirkungwird standardmäßig verwendet viewModelScope auf Android und benutzerdefinierter Bereich auf iOS
Updater
Hier entscheiden wir wie Wir wollen den Zustand basierend auf der empfangenen Aktion ändern, wir müssen eine Klasse erstellen, die implementiert Updater Schnittstelle, die nur eine Methode hat, die einen neuen Zustand und (vielleicht) einen neuen zurückgibt Nebenwirkungen eingewickelt in a Nächste Objekt.
Beachte das Filme abrufen () Methode gibt a zurück NächstesErgebnis ein Objekt, das a enthält Nebenwirkung, besonders Filme laden eins. So Prozessor werden über diesen neuen Beitrag benachrichtigt Nebenwirkung und führt eine HTTP-Anforderungsoperation aus
Prozessor
Jetzt müssen wir umsetzen Prozessor Schnittstelle die eine einzigartige Suspend-Funktion hat, die die Aktion wiederherstellt.
TMDApi Klasse ist dafür verantwortlich, HTTP-Anforderungen zu erstellen, um Filme abzurufen, und json-Antworten in eine Reihe von Filmen umzuwandeln. Es ist uns egal, wie es implementiert wird, aber wenn Sie neugierig sind, können Sie sich jederzeit das vollständige Democode-Repository unter der Haube ansehen von Ktor verwendet.
Sobald wir die Liste der Filme erhalten haben, senden wir einfach eine Aktion, um sie im Status zu speichern.
ViewModel
Wir haben es fast geschafft, jetzt müssen wir all diese Klassen, die wir implementiert haben, zusammenführen ViewModel die erben müssen ArchViewModel
Ja! das ist unser ganzer Code ViewModel braucht.
Beachten Sie, dass wir den Anfangszustand und den Anfangseffekt eingestellt haben.
Beobachten Sie Änderungen in der Situation
Der letzte Schritt, beobachten Sie einfach die Zustandsänderung! aber wie?
ArchViewModel entlarvt a Fließen die alle Zustandsänderungen ausgibt, also müssen wir sie nur sammeln.
Auf Android sammeln a Fließen ist einfach, aber nicht so einfach auf iOS, daher implementiert die Arch-Bibliothek Folgendes FlowWrapper
Wenn Sie eine bessere Lösung für dieses Problem des Sammelns von Kotlina haben Fließt aus Swift-Code, ich würde ihn gerne lesen.
Schauen wir uns den endgültigen Code an:
Und das ist alles! Denken Sie daran, dass es sich um einen vollständigen Code handelt Hier
Aus der Perspektive von Android-Entwicklern ist die Entwicklungserfahrung mit KMM (und diesem Ansatz) so ziemlich die gleiche wie bei der reinen Entwicklung von Android. Aber für iOS-Entwickler ist die Erfahrung nicht so gut wie für Android-Entwickler, auf iOS müssen wir uns um Dinge wie Gleichzeitigkeit kümmern, Unveränderlichkeitsausnahme und andere Inkompatibilitätsprobleme, die auftreten können.
Jetbrains ist sich dieser Probleme bewusst und arbeitet daran, das Erlebnis für iOS-Entwickler zu verbessern. Am 31. August 2021 haben sie eine Vorschauversion veröffentlicht neuer Speichermanager Dies sollte uns von der Notwendigkeit befreien, Artikel einzufrieren.
Diese Architektur eignet sich hervorragend für Teams, die große native Apps für iOS und Android verwalten, insbesondere wenn die Entwickler in Ihrem Team über Kenntnisse beider Plattformen verfügen.
Normalerweise haben iOS- und Android-Versionen derselben Anwendung unterschiedliche Architekturen wie MVC, MVP, MVVM, VIPER oder Redux. Die Beibehaltung derselben Architektur auf beiden Plattformen hat viele Vorteile, erfordert weniger Arbeit und hilft, Aufgaben besser auf Ihr Team zu verteilen, sogar Entwickler können dies tun sehr einfach auf beiden Plattformen funktionieren.
Alles in allem glaube ich nicht, dass es die perfekte Lösung gibt, jedes Team muss sich überlegen, welche für seine Bedürfnisse am besten geeignet ist.