Einleitung

Zustandswiederherstellung ist eine grundlegende Säule der modernen iOS-Entwicklung, die direkt beeinflusst, wie Benutzer die Zuverlässigkeit und Polierbarkeit Ihrer Anwendung wahrnehmen. Wenn ein Benutzer zu einer anderen App wechselt, einen Anruf erhält oder das Gerät herunterfährt, erwarten sie, dass sie genau dorthin zurückkehren, wo sie aufgehört haben - nicht zu einem leeren Bildschirm oder einer verlorenen Form. Die Implementierung einer ordnungsgemäßen App-Statuswiederherstellung gewährleistet diese Kontinuität, reduziert Frustration und baut Vertrauen auf. Über die grundlegende Benutzerbequemlichkeit hinaus spielt die Zustandswiederherstellung auch eine Schlüsselrolle bei der Aufrechterhaltung einer nahtlosen Erfahrung nach einer systeminitiierten Beendigung, wie z. B. wenn iOS Speicher zurückgewinnen muss. Ohne Wiederherstellung können Benutzer ungespeicherte Arbeit, Navigationskontext oder teilweise abgeschlossene Aufgaben verlieren, was zu hohen Abbruchraten führt. Dieser Artikel bietet eine umfassende Anleitung zum Umgang mit App-Statuswiederherstellung in iOS-Anwendungen, UIKit- und SwiftUI-Ansätze, Best Practices, häufige Fallstricke und praktische Strategien für Code auf Produktionsebene.

Den Wiederherstellungsprozess des Staates verstehen

Key Concepts und API Überblick

Die Zustandswiederherstellung in iOS basiert auf einem kooperativen Satz von UIKit-APIs, die es Ihrer Anwendung ermöglichen, den Zustand ihrer Benutzeroberfläche und der zugehörigen Daten zu erhalten und wiederherzustellen. Der Kernmechanismus dreht sich um das -Protokoll, das Ihre View-Controller und andere Objekte übernehmen, um ihren Zustand zu codieren und zu dekodieren. Jedes wiederherstellbare Objekt muss eine -Wiederherstellungskennung haben, eine eindeutige Zeichenfolge, die UIKit verwendet, um den gespeicherten Zustand mit der richtigen Objektinstanz über Starts abzugleichen. Die Zustandsdaten werden mit serialisiert, dem gleichen Archivierungsmechanismus, der für und verwendet wird. UIKit verwaltet automatisch das Speichern und Laden des Wiederherstellungsarchivs - typischerweise eine Plist-Datei - zu geeigneten Zeiten, z. B. wenn die App in den Hintergrund wechselt oder beendet wird.

Szenenbasierte Zustandsrestaurierung in modernem iOS

Seit iOS 13 hat sich das Multitasking-Paradigma mit der Einführung von und vom app-basierten auf den szenebasierten Lebenszyklus verschoben. Das Zustandswiederherstellungssystem wurde aktualisiert, um mehrere Szenen zu unterstützen, jede mit ihrem eigenen Wiederherstellungsarchiv. Anstatt sich ausschließlich auf die und Methoden des App-Delegierten zu verlassen, verwenden Sie jetzt die entsprechenden Methoden des Szenedelegierten: und . Jede Szene erhält ein einzigartiges Wiederherstellungsarchiv, das an ihre Szenensitzung gebunden ist. Diese Änderung erfordert eine Verschiebung des Denkens: Wiederherstellung ist kein Single-App-Konzept mehr, sondern eine Verantwortung pro Szene. Sie müssen sicherstellen, dass Wiederherstellungskennungen innerhalb jeder Szene eindeutig sind und dass die View-Controller-Hierarchie korrekt neu erstellt wird, wenn eine Szene wiederhergestellt wird.

Durchführungsstaat-Erhaltung

Zuweisung von Restoration Identifiers

Der erste Schritt zur Zustandserhaltung besteht darin, jedem Ansichtscontroller, den Sie wiederherstellen möchten, Wiederherstellungskennungen zuzuweisen. Diese Kennungen können im Interface Builder über das Feld Wiederherstellungs-ID oder programmgesteuert unter Verwendung der -Eigenschaft festgelegt werden. Beispielsweise kann ein Einstellungsansichtscontroller den Kennungskennzeichen haben. Der Kennungskennzeichen muss im Kontext der Szene oder App eindeutig sein, abhängig von Ihrer Architektur. UIKit verwendet den Wiederherstellungskennzeichen, um die Objekthierarchie während der Wiederherstellung zu erstellen. Wenn Kennungen fehlen oder dupliziert werden, schlägt die Wiederherstellung fehl oder führt zu falschen Ergebnissen. Eine gute Praxis besteht darin, Wiederherstellungskennungen als Konstanten in einem dedizierten Enum oder einer Struktur zu definieren.

Kodierungszustand mit encodeRestorableState

Sobald Wiederherstellungskennungen vorhanden sind, implementieren Sie in jedem Ansichtscontroller, der zum gespeicherten Zustand beiträgt. Innerhalb dieser Methode schreiben Sie die Daten, die erforderlich sind, um die Benutzeroberfläche und den Kontext des Ansichtscontrollers in die bereitgestellte Instanz wiederherzustellen. Zum Beispiel könnte ein Formularansichtscontroller die aktuelle Textfeldeingabe, den ausgewählten Index eines Pickers oder die Scrollposition einer Tabellenansicht speichern. Nur das Wesentliche codieren - vermeiden Sie das Speichern großer Datensätze oder zwischengespeicherter Bilder. Verwenden Sie , und ähnliche Methoden. Beachten Sie, dass der Coder automatisch archiviert wird und nicht für sensible Informationen verwendet werden sollte, da die Wiederherstellungsdatei auf der Festplatte gespeichert ist.

override func encodeRestorableState(with coder: NSCoder) {
 super.encodeRestorableState(with: coder)
 coder.encode(selectedSegmentIndex, forKey: "selectedSegmentIndex")
 coder.encode(searchQuery, forKey: "searchQuery")
}

Bewahren des Anwendungszustands in App oder Szene Delegierter

Zusätzlich zur Pro-View-Controller-Kodierung müssen Sie UIKit mitteilen, ob der Status auf Anwendungs- oder Szenenebene gespeichert werden soll. Für Apps, die den App-Delegierten-Lebenszyklus verwenden, implementieren Sie und geben Sie zurück. Für szenenbasierte Apps verwenden Sie die -Methode, um eine bereitzustellen, die leichte Wiederherstellungsinformationen enthält. Das schwere Heben – der Vollansichts-Controller-Zustand – wird automatisch von UIKit gespeichert, wenn es die gesamte Wiederherstellungshierarchie codiert. Sie können jedoch anpassen, welche Metadaten gespeichert werden, indem Sie oder das Äquivalent des Szenedelegierten implementieren. Diese Methode ermöglicht es Ihnen, einen app-weiten oder szeneweiten Zustand hinzuzufügen, bevor UIKit das Archiv schreibt.

Durchführungsstaat Restaurierung

Decodierungszustand mit decodeRestorableState

Wenn die App startet und UIKit feststellt, dass eine Wiederherstellung erfolgen soll (basierend auf dem Rückgabewert von oder seinem Szene-Pendant), baut sie die View-Controller-Hierarchie mit dem Storyboard oder der programmatischen Instanziierung um, ruft dann auf jedem wiederherstellbaren View-Controller auf. Bei dieser Methode lesen Sie die codierten Werte mit , usw. zurück und wenden sie an, um die Benutzeroberfläche in ihren vorherigen Zustand wiederherzustellen. Immer mit fehlenden Tasten anmutig umgehen - das Wiederherstellungsarchiv kann unvollständig sein oder aus einer früheren Version der App stammen. Verwenden Sie optionale Bindung und bieten Sie vernünftige Standardwerte an.

override func decodeRestorableState(with coder: NSCoder) {
 super.decodeRestorableState(with: coder)
 selectedSegmentIndex = coder.decodeInteger(forKey: "selectedSegmentIndex")
 searchQuery = coder.decodeObject(forKey: "searchQuery") as? String ?? ""
}

Wiederherstellung der View Controller-Hierarchie

Die Rekonstruktion der View-Controller-Hierarchie erfolgt automatisch, wenn Sie Storyboards verwenden und die Wiederherstellungskennung mit einer Storyboard-Kennung übereinstimmt. Bei programmgesteuert erstellten Hierarchien müssen Sie im App-Delegierten implementieren oder das Äquivalent des Szenedelegierten verwenden. Diese Methode sollte den View-Controller mit dem angegebenen Restaurierungskennungspfad instanziieren und zurückgeben. UIKit fährt dann mit dem Durchlaufen fort, um Child-View-Controller wiederherzustellen. Stellen Sie sicher, dass die Restaurierungskennung des zurückgegebenen View-Controllers mit der letzten Pfadkomponente übereinstimmt, um eine unendliche Rekursion zu vermeiden. Bei komplexen, Multi-Window-Apps wird dieser Schritt entscheidend für die Wiederherstellung der korrekten Konfiguration.

Umgang mit Datenkonsistenz

Zustandswiederherstellung kann fragil sein, wenn sich Datenabhängigkeiten zwischen Anwendungsstarts ändern. Zum Beispiel könnte ein Benutzer zu einer Detailansicht eines Elements navigiert haben, das später vom Server gelöscht wurde. Immer validieren, dass der wiederhergestellte Zustand immer noch sinnvoll ist, bevor er angewendet wird. Wenn sich die kodierten Daten auf ein Modellobjekt beziehen, das nicht mehr existiert, kehren Sie in einen Standardzustand zurück, z. B. eine leere Ansicht oder eine neue Liste anzeigen. Vermeiden Sie in ähnlicher Weise die Wiederherstellung des Zustands, der von Netzwerkanforderungen oder großen Datenbank-Rechenwerten abhängt, die möglicherweise nicht rechtzeitig abgeschlossen werden. Stellen Sie stattdessen einen Platzhalterzustand wieder her und laden Sie die tatsächlichen Daten asynchron. Verwenden Sie oder , um diese Updates auszulösen.

Fortgeschrittene Themen

State Restoration mit SwiftUI

SwiftUI bietet eine deklarative Alternative zur Zustandswiederherstellung von UIKit. Die Schlüssel-API ist der -Eigenschafts-Wrapper, der automatisch kleine Datenmengen pro Szene an UserDefaults festhält. Zum Beispiel können Sie den ausgewählten Registerkartenindex oder einen Suchbegriff speichern. Für einen komplexeren Zustand integriert sich SwiftUI in das -Protokoll und die -APIs. Verwenden Sie den -Modifikator, um die Wiederherstellung von Handoff- oder Systemaktivitäten zu handhaben. SwiftUI unterstützt auch die Zustandswiederherstellung für und automatisch, wenn Sie geeignete Identifikatoren verwenden. Beachten Sie jedoch, dass die Zustandswiederherstellung von SwiftUI eingeschränkter ist als die von UIKit – sie speichert und stellt nicht automatisch die vollständige Ansichts-Controller-Hierarchie wieder her. Sie müssen den wichtigen Zustand explizit mit , oder einer benutzerdefinierten Persistenz

Restaurierung in komplexen Sichthierarchien

Wenn Ihre App verschachtelte Split Views, Page View Controller oder Container Controller enthält, wird die Zustandswiederherstellung schwieriger. Jeder Child View Controller muss seine eigene Wiederherstellungskennung haben und seinen eigenen Zustand kodieren. Zusätzlich muss der übergeordnete Container die Wiederherstellung seiner Kinder ordnungsgemäß verwalten. Zum Beispiel muss ein implementieren, um den Index der aktuellen Seite zu speichern und den Pfad der Wiederherstellungskennung zu verwenden, um die bestellten Kinder neu zu erstellen. In ähnlicher Weise behandeln und automatisch die Wiederherstellung ihrer Child View Controller, wenn Wiederherstellungskennungen korrekt zugewiesen sind. Testen Sie diese Hierarchien immer durch Force-Quitting der App und Relaunching; verwenden Sie die “Trigger Memory Warning” des Simulators, um die Beendigung zu simulieren.

Asynchrones Datenladen

Eine häufige Falle ist der Versuch, den Zustand wiederherzustellen, der von asynchronen Daten abhängt, wie z. B. einer Tabellenansicht, die Ergebnisse aus einer Netzwerkanforderung anzeigt. Der Wiederherstellungsprozess erfolgt synchron während des Starts, bevor Netzwerkaufrufe gestartet werden. Wenn Sie versuchen, einen Ansichtscontroller mit gespeicherten Daten zu füllen, die noch nicht verfügbar sind, erscheint die Wiederherstellung unvollständig oder leer. Die Lösung besteht darin, nur die metadaten wiederherzustellen, die zum Refetchen der Daten benötigt werden (z. B. die Kennung des zuletzt angezeigten Elements oder eine Abfragezeichenfolge). In oder initiieren Sie dann einen asynchronen Abruf und aktualisieren Sie die Benutzeroberfläche, sobald Daten ankommen. Sie können auch Zustandswiederherstellung mit Hintergrundaufgaben kombinieren, um Caches vor dem Warmwerden zu erstellen, aber die Benutzeroberfläche reagiert.

Testzustandswiederherstellung

Eine gründliche Prüfung der Zustandswiederherstellung ist unerlässlich, wird aber oft übersehen. Der einfachste Weg zum Testen ist die Verwendung des iOS-Simulators: Starten Sie Ihre App, navigieren Sie in einen bestimmten Zustand, drücken Sie die Home-Taste, dann stoppen Sie die App von Xcode. Starten Sie die App neu und überprüfen Sie, ob der Zustand wiederhergestellt ist. Aktivieren Sie für realistischere Szenarien die Option „Speicher-Warnung simulieren im Debug-Menü des Simulators. Dies zwingt das System, die App zu beenden, und beim Neustart sollte die Zustandswiederherstellung eingeschaltet werden. Testen Sie außerdem mit verschiedenen Geräteorientierungen, Multitasking-Split-Views und nach Unterbrechungen wie Telefonanrufen. Verwenden Sie die Konsolenprotokolle, um nach wiederherstellungsbezogenen Warnungen oder Fehlern zu suchen, wie fehlende Wiederherstellungskennungen.

Best Practices für eine robuste Wiederherstellung des Staates

  • Restaurationsdaten minimal halten: Kodieren Sie nur die Informationen, die erforderlich sind, um den Kontext des Benutzers zu rekonstruieren – vermeiden Sie das Speichern großer Blobs, Bilder oder ganzer Modellgraphen.
  • Verwenden Sie eindeutige und stabile Wiederherstellungskennungen: Hardcode-Strings oder definieren Sie Konstanten; Verwenden Sie niemals automatisch generierte IDs, die zwischen Builds wechseln können.
  • Validieren des wiederhergestellten Zustands: Überprüfen Sie immer, ob wiederhergestellte Daten noch gültig sind und dass referenzierte Modellobjekte existieren, bevor Sie den Zustand anwenden.
  • Verwalte die Versionierung mit Anmut: Wenn sich das Datenmodell deiner App ändert, implementiere Versionsprüfungen in deiner Codierungs-/Decodierungslogik, um Abstürze zu vermeiden.
  • Kombinieren Sie mit NSUserActivity: Für eine leichte Wiederherstellung (z. B. Fortsetzung eines FaceTime-Aufrufs oder einer Suchanfrage) verwenden Sie neben der vollständigen Wiederherstellung für beste Ergebnisse.
  • Respektiere die Privatsphäre der Nutzer: Niemals sensible Daten wie Passwörter, Kreditkartennummern oder persönliche Gesundheitsinformationen im Wiederherstellungsarchiv kodieren.
  • Set-Restaurationsklasse für programmgesteuerte View-Controller: Wenn Sie View-Controller ohne Storyboard erstellen, setzen Sie ihre -Eigenschaft auf eine Klasse, die weiß, wie man sie instantiiert.
  • Test mit Startargumenten: Verwenden Sie das Startargument, um das Restaurierungsarchiv während der Entwicklung zu inspizieren.

Häufige Fallstricke und wie man sie vermeidet

  • Missing restoration identifiers on child view controllers: Jeder view controller, der in der wiederhergestellten Hierarchie erscheint, muss eine restoration identifier haben, einschließlich derjenigen, die in Navigationscontrollern oder Tab-Bar-Controllern eingebettet sind.
  • Zustand codiert, aber nie decodiert, weil sich die Ansichtshierarchie geändert hat: Wenn Sie Ihr Storyboard umstrukturieren oder die Reihenfolge der Ansichtscontroller ändern, kann der zuvor codierte Zustand verwaist werden.
  • Wiederherstellung versucht bei einer Neuinstallation oder nach dem App-Update: Die Zustandswiederherstellung wird nur aufgerufen, wenn die App zuvor ausgeführt wurde. Nach einer Neuinstallation oder einem Update, das die Sandbox löscht, existiert kein Archiv. Ihr Code sollte dies ohne Abstürze anmutig handhaben.
  • Überschreiben Zustand während der Dekodierung: Vermeiden Sie es, von innen heraus zu rufen.
  • Das Ignorieren von Szenenverbindungen und -trennungen: In szenenbasierten Apps gilt die Zustandswiederherstellung pro Szene.
  • Wiederherstellung asynchroner Vorgänge zu früh: Verlassen Sie sich nicht auf Netzwerkaufrufe, die vor dem Ende der Wiederherstellung abgeschlossen werden.

Externe Ressourcen und weitere Lesung

For an in-depth understanding of UIKit’s state restoration, start with Apple’s official documentation on Preserving Your App’s UI. The WWDC 2014 session “State Restoration in Practice” covers many real-world scenarios. For SwiftUI-specific guidance, refer to the SceneStorage documentation. A comprehensive third-party tutorial can be found on Ray Wenderlichs Website Schließlich enthält der Apple View Controller Programming Guide (archiviert, aber immer noch relevant) detaillierte Ratschläge zu Wiederherstellungskennungen und dem Unarchivierungsprozess.

Schlussfolgerung

App-Statuswiederherstellung ist keine optionale Funktion – sie ist ein erwarteter Teil einer gut gestalteten iOS-Anwendung. Benutzer investieren Zeit in die Navigation durch Ihre Benutzeroberfläche, das Ausfüllen von Formularen und das Erkunden von Inhalten; die Fähigkeit, diese Erfahrung nach einer Unterbrechung nahtlos wieder aufzunehmen, wirkt sich direkt auf die Benutzerzufriedenheit und -bindung aus. Durch das Verständnis der UIKit-Statuswiederherstellungs-APIs, die Implementierung geeigneter Wiederherstellungskennungen, die Kodierung nur notwendiger Daten und die Handhabung von Randfällen wie Datenänderungen und asynchronen Operationen können Sie eine robuste Erfahrung liefern, die sich zuverlässig und poliert anfühlt. Ob Sie eine alte UIKit-App pflegen oder eine neue SwiftUI-Schnittstelle erstellen, die Prinzipien bleiben die gleichen: antizipieren Sie den Kontext des Benutzers, bewahren Sie ihn nachdenklich und restaurieren Sie es anmutig. Mit sorgfältiger Planung und gründlichen Tests wird die Zustandswiederherstellung zu einem natürlichen Teil Ihres Entwicklungsworkflows und nicht ein nachträglicher Einfall.

Denken Sie daran, dass das Ziel nicht darin besteht, jedes Pixel der vorherigen Sitzung zu replizieren, sondern die Absicht des Benutzers wiederherzustellen. eine erfolgreiche Zustandswiederherstellung lässt den Benutzer sich fragen, ob die App jemals wirklich geschlossen wurde - und das ist das höchste Kompliment.