SwiftUI Best Practices: Mehrere State-Properties zusammenfassen

Bei der Arbeit mit SwiftUI kommt man des Öfteren in eine Situation, in der eine View mehrere State-Properties benötigt. Ein typisches Beispiel sind Formulare, mit denen man verschiedene Informationen auf einmal einsieht und bearbeitet. Da diese am Ende zusammengefasst werden sollen, ist es notwendig, dass die zugrundeliegende View jede einzelne Information kennt und direkt darauf zugreifen kann. Ein konkretes Beispiel deutet das folgende Listing an:

struct AddressView: View {
    @State private var name = ""
    @State private var street = ""
    @State private var postalCode = ""
    @State private var city = ""
    @State private var country = ""
    
    var body: some View {
        Form {
            // Implementierung des Formulars ...
        }
    }
}

Die hier definierte AddressView besitzt die Aufgabe, neue Adresseinträge zu erstellen. Da sich eine Adresse aus verschiedenen Informationen wie Straße, Postleitzahl und Ort zusammensetzt, verwaltet AddressView jede dieser Informationen mithilfe einer separaten State-Property.

Technisch funktioniert das zwar prinzipiell einwandfrei, ist aber nicht sonderlich schön anzusehen. Darüber hinaus bin ich persönlich der Meinung, dass SwiftUI-Views im Idealfall nicht mehr als eine Source of Truth besitzen sollten. Da jede einzelne State-Property aber eine neue Source of Truth definiert, haben wir es im gezeigten Beispiel mit insgesamt fünf Sources of Truth für AddressView zu tun.

Erfreulicherweise lässt sich das gezeigte Beispiel aber ganz simpel optimieren. Dazu definiert man eine eigene Structure, die Properties für all jene Eigenschaften besitzt, die bisher mittels State direkt in AddressView eingebunden sind. Anschließend erzeugt man innerhalb von AddressView nur noch eine einzige State-Property auf Basis der neuen Structure:

struct AddressInformation {
    var name = ""
    var street = ""
    var postalCode = ""
    var city = ""
    var country = ""
}

struct AddressView: View {
    @State private var addressInformation = AddressInformation()
    
    var body: some View {
        Form {
            // Implementierung des Formulars ...
        }
    }
}

Die neue Structure erlaubt den Zugriff auf alle Eigenschaften, die AddressView benötigt. Jedoch sind all diese Eigenschaften nun nicht mehr einfach Teil der View, sondern schön ordentlich in einem eigene Typ namens AddressInformation verpackt. Den kann man langfristig auch problemlos erweitern, sollten noch zusätzliche Daten innerhalb von AddressView benötigt werden.

Mit diesem Pattern kann man SwiftUI-Views, die mehrere State-Properties benötigen, ordentlich entschlacken. Das macht den Code übersichtlicher und hilft dabei, View und Daten besser voneinander zu trennen.

Euer Thomas


Kommentare

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert