- Notifications
You must be signed in to change notification settings - Fork13
Flutter plugin to help restoring state after the app process was killed
License
littlerobots/flutter-native-state
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Now that Flutter officially supports state restoration throughRestorationManagerthis plugin is no longer needed. Please switch to using the official Flutter APIs for saving state.
This plugin allows for restoring state after the app process is killed while in the background.
Since mobile devices are resource constrained, both Android and iOS use a trick to make it look like apps like always running inthe background: whenever the app is killed in the background, an app has an opportunity to save a small amount of datathat can be used to restore the app to a state, so that itlooks like the app was never killed.
For example, consider a sign up form that a user is filling in. When the user is filling in this form, and a phone call comes in,the OS may decide that there's not enough resources to keep the app running and will kill the app. By default, Flutter does notrestore any state when relaunching the app after that phone call, which means that whatever the user has entered has now been lost.Worse yet, the app will just restart and show the home screen which can be confusing to the user as well.
First of all: the term "state" may be confusing, since it can mean many things. In this casestate means: thebare minimumamount of data you need to make it appear that the app was never killed. Generally this means that you should only persist things likedata being entered by the user, or an id that identifies whatever was displayed on the screen. For example, if your app is showinga shopping cart, only the shopping cart id should be persisted using this plugin, the shopping cart contents related to this idshould be loaded by other means (from disk, or from the network).
This plugin uses Kotlin, make sure your Flutter project has Kotlin configured for that reason.No other setup is required.
Note that as of version 1.1.0, Flutter version 1.12 or up is required and you shouldmigrate your projectbefore updating from an older version of this plugin.
This plugin uses Swift, make sure your project is configured to use Swift for that reason.
YourAppDelegate.swift in theios/Runner directory should look like this:
import UIKitimport Flutter // add this lineimport native_state@UIApplicationMain@objcclassAppDelegate:FlutterAppDelegate{overridefunc application( _ application:UIApplication, didFinishLaunchingWithOptions launchOptions:[UIApplicationLaunchOptionsKey:Any]?)->Bool{GeneratedPluginRegistrant.register(with:self)return super.application(application, didFinishLaunchingWithOptions: launchOptions)} // add these methodsoverridefunc application(_ application:UIApplication, didDecodeRestorableStateWith coder:NSCoder){StateStorage.instance.restore(coder: coder)}overridefunc application(_ application:UIApplication, willEncodeRestorableStateWith coder:NSCoder){StateStorage.instance.save(coder: coder)}overridefunc application(_ application:UIApplication, shouldSaveApplicationState coder:NSCoder)->Bool{returntrue}overridefunc application(_ application:UIApplication, shouldRestoreApplicationState coder:NSCoder)->Bool{returntrue}}
TheSavedStateData class allows for storing data by key and value. To get access toSavedStateData wrap yourmain application in aSavedState widget; this is the global applicationSavedState widget. To retrieve theSavedStateDatauseSavedState.of(BuildContext) or use theSavedState.builder() to get the data in a builder.
SavedState widgets manage the saved state. When they are disposed, the associated state is also cleared. Usually you want towrap each page in your application that needs to restore some state in aSavedState widget. When the page is no longer displayed, theSavedState associated with the page is automatically cleared.SavedState widgets can be nested multiple times, creating nestedSavedStateData that will be cleared when a parent of theSavedStateData is cleared, for example, when theSavedState widget is removedfrom the widget tree.
Most of the time, you'd want yourStatefulWidgets to update theSavedState. UseSavedState.of(context) then callstate.putXXX(key, value) toupdate the state.
To restore state in yourStatefulWidget add theStateRestoration mixin to yourState class. Then implement therestoreState(SavedState)method. This method will be called once when your widget is mounted.
Restoring the page state is one part of the equation, but when the app is restarted, by default it will start with the default route,which is probably not what you want. The plugin provides theSavedStateRouteObserver that will save the route to theSavedState automatically. The saved route can then be retrieved usingrestoreRoute(SavedState) static method.Important note: forthis to work you need to setup your routes in such a way that theNavigator will restore them when youset theinitialRoute property.
Another requirement is that you set anavigatorKey on theMaterialApp. This is because the tree is rebuilt after theSavedState is initialised. Whenrebuilding, the Flutter needs to reuse the existingNavigator that receives theinitialRoute.
Lucky you! Your phone must have infinite memory :)
Two reasons: you are wasting resources (disk and battery) when saving all app state, usingnative_state is more efficient as it only saves the bareminimum amount of data and only when the OS requests it. State is kept in memory so there are no disk writes at all.
Secondly, even though the app state might have saved, the OS mightchoose not to restore it. For example, when the user has killed your app from the task switcher, or after some amount of time whenit doesn't really make sense any more to restore the app state. This is up to the discretion of the OS, and it is good practiceto respect that, in stead ofalways restoring the app state.
For both Android and iOS: start your app and send it to the background by pressing the home button or using a gesture. Thenfrom XCode or Android Studio, kill the app process and restart the app from the launcher. The app should resume from the samestate as when it was killed.
For Android: when the user "exits" the app by pressing back, and at the discretion of the OS when the app is in the background.
For iOS: users cannot really "exit" an app on iOS, but state is cleared when the user swipes away the app in the app switcher.
Licensed under the Apache License, Version 2.0 (the "License");you may not use this file except in compliance with the License.You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed under the License is distributed on an "AS IS" BASIS,WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.See the License for the specific language governing permissions andlimitations under the License.About
Flutter plugin to help restoring state after the app process was killed
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors5
Uh oh!
There was an error while loading.Please reload this page.