State Restoration per SceneDelegate (iOS 13)

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

  • State Restoration per SceneDelegate (iOS 13)

    Moin!

    Hat jemand von Euch schon einmal State Restoration per UISceneDelegate unter iOS 13 implementiert?

    Ich war mir dieser Neuerung gar nicht bewusst und habe heute etwas dumm aus der Wäsche geschaut, als die „Legacy“-Methoden im AppDelegate nicht mehr angesprungen wurden. Nach etwas Googlen war dann klar, dass es an der Mehr-Fenster- (aka „Scenes“) -Unterstützung on iOS 13 liegt. Natürlich könnte ich darauf verzichten und das herkömmlich System mit Encoding / Decoding der ViewController verwenden ... aber ich möchte den neuen Weg verstehen und benutzen.

    An ersterem hapert es noch etwas: Der SceneDelegate liest aus der UserInfo einer persistierten NSUserActivity die für die Restoration notwendigen Daten. Aber für deren Speicherung / Wiederherstellung müsste er ja die komplette View-Hierarchie aufbauen und Internas aller VCs kennen. Das erscheint mir als riesen Rückschritt und ich vermute ein Verständnisproblem.

    Am liebsten würde ich die UserInfo an alle VCs geben, die dann ihrerseits ihre abhängigen Objekte instanzieren / konfigurieren. So scheint es auch per scene.useractivity und ihrer Delegate-Methode machbar zu sein. Aber mir ist unklar, wie ich dies bei einer UISplitView-basierten App mit Storyboard machen würde.

    Kennt jemand Quellen, die nicht nur - wie das Apple-Beispiel - auf einer ganz einfachen View-Hierarchie aufsetzen?

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Ich bin nun etwas weiter:
    1. Eine Activity wird - wenn bereits vorhanden, sonst neu instanziert - im SceneDelegate als stateRestorationActivityForScene gesetzt. So wird diese beim Disconnect der Scene automatisch persistiert und bei (Re-)Connect geladen.
    2. Alle relevanten View-Controller bekommen diese Activity als userActivity zugewiesen und erhalten so in updateUserActivityState: die Chance, ihre Statusinformationen bei Disconnect der Scene zu setzen.
    3. Der SceneDelegate schaut beim Connect in scene:willConnectToSession:options: nach, ob für die Session eine stateRestorationActivity vorliegt.
    4. Falls ja, würde deren userInfo-Dictionary benutzt, um bei Aufbau der View-Hierarchie alle notwendigen Zustandsinfos zu holen (auch sowas wie Scroll-Positionen?) und die View-Hierarchie aufzubauen. Der Punkt ist noch offen, weil ich diesen Rückschritt einfach nicht glauben will. Letztlich könnte man die Restore-Activity aber in den viewDidLoads der View-Controller nutzen.
    Soweit, so gut, aber es bleibt der Haupt-Knackpunkt:

    Muss mein SceneDelegate wirklich im Falle einer State-Restoration alle View-Controller in der korrekten Hierarchie instanzieren und dann über pushs etc. den letzen Status rekonstruieren? Ich will das einfach noch nicht glauben: Schon bei einer Splitview mit zwei Navigation-Stacks, Master- und Detail-ViewController etc. wird das beliebig komplex, insbesondere weil sich die View-Hierarchie auf iPads und iPhones massgeblich unterscheidet.

    Gibt es nicht einen besseren Weg? Falls nicht, überlege ich ernsthaft, Scene-Support vorerst zu kippen und auf die legacy State Restoration zu setzen.

    Vollkommen verwirrt, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Neustes Update: DIe Google-Wüste belebt sich etwas, wenn man berücksichtigt, das die neue State Restoration eigentlich nur eine spezielle Behandlung von Handoff ist. Ich habe hier bei den üblichen Verdächtigen eine ausführliche Beschreibung von Handoff einer UISplitView-App gefunden ... das sollte als Hilfestellung reichen, ich muss es noch in Ruhe verdauen. Ein kurzer Überblick bestätigt aber den obigen Ansatz, per Delegate-Methoden in den jeweiligen VC zu agieren.

    Mal sehen, vielleicht fällt dabei Handoff-Support als "Goodie" mit ab...

    Blöd ist eigentlich nur, dass ich mich mit der App auf der Zielgerade wähnte und nun doch noch etwas mehr ansteht ... aber ich habe ja keinen festen Abgabetermin :)

    Mattes - im Selbstgespräch
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Für die Akten, falls mal jemand über diesen Versuch einer Selbsttherapie stolpert: Ich habe das Thema "iOS 13 State Restauration / Handoff" erst einmal auf Eis gelegt und werde die Legacy-Methode verwenden. Gründe:
    • Meine App unterstützt kein Multi-Window und benötigt daher nicht zwingend UIScene-Support.
    • Ein Goodie wäre Handoff gewesen; hierzu müsste ich mit Cloud-Kit synchronisierte Core-Data-Objekte zur Wiederherstellung an das andere Device geben. Leider weichen die UTIs der ObjectIDs ab und ich habe momentan keine Lust, mein Datenmodell um einen eigenen Identifier aufzubohren.
    • Ich tue mich extrem schwer damit, die Wiederherstellung über alle ViewController auf Basis einer NSUserActivity zu implementieren. Das Ganze ist zeitlich etwas kritisch, da die UserInfo der Aktivität beim dem Prozess teilweise bereits gelöscht wird. Ein möglicher Ansatz über Kopien findet man hier in der Antwort auf SO. Allerdings bildet dies mehr oder minder die iOS12-er Mimik nach ... wo bleibt da - ohne Handoff und Multiscene - der Mehrwert?
    Ich würde das Thema gerne später in einer Folgeversion der App wieder aufgreifen, insbesondere Handoff reizt mich - obwohl ich kaum jemanden kenne, der es verwendet und bisher nur bei Apple-Apps unterstützt gesehen habe.

    Wenn jemand von Euch hier Erfahrungen sammelt, würde ich mich über einen Austausch freuen. Momentan finde ich im Netz zu wenig komplexere Anwendungen (mit UISplitView, Core Data, ...) und bin als Solo-Kämpfer überfordert.

    Leicht gefrustet, Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • MyMattes schrieb:

    • Ich tue mich extrem schwer damit, die Wiederherstellung über alle ViewController auf Basis einer NSUserActivity zu implementieren. Das Ganze ist zeitlich etwas kritisch, da die UserInfo der Aktivität beim dem Prozess teilweise bereits gelöscht wird. Ein möglicher Ansatz über Kopien findet man hier in der Antwort auf SO. Allerdings bildet dies mehr oder minder die iOS12-er Mimik nach ... wo bleibt da - ohne Handoff und Multiscene - der Mehrwert?
    Um diesen uralten Thread einmal aufzuwärmen:

    Ich baue gerade eine andere App (mit einfacher View-Controller-Hierarchie) um, dabei ergab sich auch die Unterstützung von Scenes und somit auch das „neue“ Verfahren mittels User Activity.

    Kurz: Es läuft genau wie oben beschrieben:
    • Der SceneDelegate stellt ein Aktivität zur Verfügung, die alle View Controller ihrem Property userActivity zuweisen. Dadurch wird für jeden VC der Responder Chain updateUserActivityState: angesprungen, wenn die Scene in den Hintergrund wechselt, so dass Infos im userInfo der Activity gespeichert werden können.
    • Beim Verbinden der Scene wird auf eine bestehende Restore-Activity geprüft, der erste VC vom SceneDelegate hergestellt und ihm die userInfo als Dictionary weitergereicht. Das geschieht nun entlang der wiederherzustellenden View-Hierarchie, wobei die Infos z. B. im viewWillAppear: genutzt werden, anschliessen wird das Dictionary gelöscht.
    Läuft gut, sieht clean aus, aber ich kann nicht verstehen, warum Apple das alte Verfahren mittels Encoding / Decoding nicht auf Scenes angewendet hat. Wahrscheinlich wollten sie UserActivities - für Handoff, Siri etc. eingeführt - einfach auch hier nutzen, ohne Rücksicht auf Verluste. Bei komplexen View-Hierarchien sicherlich kein Spass…

    Aber ich habe eh das Gefühl, dass kaum noch eine App State Restoration implementiert.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.