Flutter Development - Ein Tech-Stack mit Redux, Hive & Co [Part 1 - Übersicht]

Größere Projekte erfordern auch in Flutter eine gut durchdachte Struktur - ein von uns für Flutter Projekte eingesetzter App-Stack wird vorgestellt.

Einleitung

Seit einigen Jahren entwickeln wir hybride Apps mit Flutter. Der Vorteil liegt dabei darin, dass eine einzige Codebasis genutzt werden kann, um sowohl iOS als auch Android Apps zu entwickeln. Dies ermöglicht uns die Bedienung beider Plattformen mit geringem Mehraufwand und entsprechend schnellen Entwicklungszeiten.

Dabei haben wir einige Erfahrungen gemacht mit verschiedenen Ansätzen zur strukturierten Entwicklung, um fehlerressistente und skalierbare Anwendungen zu erstellen. Im Folgenden möchten wir unsere Erfahrungen teilen und eine Übersicht über die am häufigsten von uns eingesetzten Packages bieten sowie zugleich auch unsere Entscheidungen dahinter beleuchten und ggf. interessante Alternativen vorstellen.

Anforderungen & Lösungen

Unsere Projekte zielen zumeist auf eine internationale Kundschaft ab, weshalb eine entsprechende Lokalisierung der App vom Beginn der Entwicklung an berücksichtigt wird. Hierfür setzen wir aktuell auf easy_localization als Package, welches die Verwaltung mehrer Sprachen in JSON-Dateien ermöglicht. Diese sind einfach zu pflegen und können bei Bedarf auch direkt durch den Kunden mithilfe von Weblate im Browser verwaltet werden. Hierbei wird der Aufwand von Textanpassungen enorm verringert und die spätere Übersetzung in mehr Sprachen jederzeit ermöglicht.

Die meisten Kunden wünschen sich regelmäßige Updates in Form neuer Funktionen. Um hier auch über mehrere Jahre hinweg zuverlässig Weiterentwicklungen umsetzen zu können, ist eine klare Struktur des Quellcodes notwendig, die zugleich auch die Fehleranfälligkeit senkt. Aufgrund guter Erfahrungen aus anderen Projekten wurde sich hierbei für das von React bekannte Redux entschieden. Redux ist ein System, um den Appstate strukturiert verwalten und bearbeiten zu können, was dabei hilft, den Umgang damit zu vereinheitlichen und ungewünschte Seiteneffekte zu vermeiden. Die relevanten Packages sind dabei redux und flutter_redux.

Um den Appstate und andere Daten persistent abzuspeichern wird in unseren Apps zumeist Hive verwendet; dieses bietet eine sehr gute Möglichkeit, Objekte einfach zu serialisieren und zu verwalten. Hive und Redux funktionieren dabei außerordentlich gut in Kombination, da Redux dafür sorgt, dass Änderungen nur über Actions erfolgen können. Eine simple Redux-Middleware prüft daraufhin, ob eine Action zu einer Änderung führt, die abgespeichert werden sollte, und kümmert sich ggf. direkt um die Sicherung dessen via Hive. Um Hive einsetzen zu können, verwenden wir die Packages hive, hive_flutter, hive_generator und build_runner, wobei letztere beiden für die automatische Generierung der Adapter zuständig sind, die für die Verwaltung durch Hive erforderlich sind. Das Package equatable hilft zudem bei der schnellen Erstellung von Datenklassen durch reduzierten Overhead.

Abschließend bietet uns get_it eine einfach zu verwendende Option für Dependency Injection in Flutter Apps. Dies wird von uns für global abrufbare Singletons, im Spezifischen meist Services, genutzt und ergänzt sich ebenfalls gut mit den obigen Packages.

Alternativen

Bisher haben sich unsere Entscheidungen als sinnvoll erwiesen; doch natürlich sind wir immer auf der Suche nach besseren Optionen, sei es durch Neuentwicklungen oder Projekten, die wir noch nicht auf dem Schirm hatten. Wir sind aktuell dabei, einige dieser Möglichkeiten auszutesten; entsprechend möchte ich hier einen kurzen Einblick in diese geben.

Die wohl spannendste Alternative aufgrund ihres potenziellen Einflusses darauf wie wir entwickeln ist riverpod. Es handelt sich um eine der bekanntesten Lösungen für Statemanagement in Flutter, welche vor kurzem durch den Release der Version 2.0 umfassend erweitert wurde. riverpod stellt dabei eine Alternative für unser aktuelles Redux-System dar und könnte auch zugleich die Nutzung von get_it substituieren. Ob es für uns die Vorteile von Redux aufrechterhält und ggf. zu effizienterer Nutzung von Entwicklungszeit führt, wird aktuell in einer Neuentwicklung von uns getestet.

Ein sehr wahrscheinlicher Wechselkandidat ist für uns Isar, ein Datenbanksystem von den Entwicklern von hive, welche dieses inzwischen ggü. hive bevorzugt empfehlen. Wir sehen darin das Potenzial, unsere Arbeit mit Datenklassen und den Umgang mit der Datenbank noch zu vereinfachen. Auch dieses System befindet sich aktuell im Zusammenspiel mit riverpod in Evaluation.

Zudem testen wir aktuell die Verwendung von intl; dieses bietet eine Alternative zur Lokalisierung durch easy_localization, die u. U. eine bessere Integration in Übersetzungsprogramme bietet. Da Weblate im Zusammenspiel mit easy_localization bisher jedoch sehr gut mit unserem Workflow vereinbar war, ist hier ein Wechsel eher unwahrscheinlich.

Boilerplate

In diesem Artikel wurden die Entscheidungen hinter den verwendeten Packages vorgestellt. In Part 2 soll genauer auf den Quellcode eingegangen und erörtert werden, wie die verschiedenen Komponenten miteinander interagieren und effizient genutzt werden können. Im Zuge dessen veröffentlichen wir auch ein komplettes Boilerplate Projekt, das eine grundsolide Struktur für größere Flutter Projekte darstellt und frei verwendet werden kann.

Wir hoffen mit dieser Reihe an Artikeln einen transparenten Einblick in unsere Entwicklungsarbeit bieten zu können und gleichzeitig anderen die Möglichkeit zu geben, aus unseren gemachten Erfahrungen zu lernen. Für Rückfragen und Wünschen zu weiteren Themen freuen wir uns jederzeit über eine Mail an blog@devsaur.de!

Leonard Sondermann
Mobile Developer

11.11.2022