{"id":13511407,"url":"https://github.com/littlerobots/flutter-native-state","last_synced_at":"2025-03-30T20:33:11.581Z","repository":{"id":54181152,"uuid":"199278098","full_name":"littlerobots/flutter-native-state","owner":"littlerobots","description":"Flutter plugin to help restoring state after the app process was killed","archived":true,"fork":false,"pushed_at":"2021-03-04T19:17:40.000Z","size":110,"stargazers_count":180,"open_issues_count":0,"forks_count":14,"subscribers_count":14,"default_branch":"develop","last_synced_at":"2025-03-12T07:27:45.796Z","etag":null,"topics":["flutter-plugin"],"latest_commit_sha":null,"homepage":"","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/littlerobots.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-28T11:21:39.000Z","updated_at":"2024-10-02T19:38:22.000Z","dependencies_parsed_at":"2022-08-13T08:31:19.243Z","dependency_job_id":null,"html_url":"https://github.com/littlerobots/flutter-native-state","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littlerobots%2Fflutter-native-state","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littlerobots%2Fflutter-native-state/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littlerobots%2Fflutter-native-state/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/littlerobots%2Fflutter-native-state/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/littlerobots","download_url":"https://codeload.github.com/littlerobots/flutter-native-state/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246379379,"owners_count":20767694,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["flutter-plugin"],"created_at":"2024-08-01T03:00:49.298Z","updated_at":"2025-03-30T20:33:11.263Z","avatar_url":"https://github.com/littlerobots.png","language":"Dart","funding_links":[],"categories":["other"],"sub_categories":[],"readme":"# Flutter native_state plugin\n[![Pub](https://img.shields.io/pub/v/native_state.svg)](https://pub.dartlang.org/packages/native_state)\n\n## Deprecation notice\nNow that Flutter officially supports state restoration through [RestorationManager](https://api.flutter.dev/flutter/services/RestorationManager-class.html)\nthis plugin is no longer needed. Please switch to using the official Flutter APIs for saving state.\n\n\nThis plugin allows for restoring state after the app process is killed while in the background.\n\n## What this plugin is for\nSince mobile devices are resource constrained, both Android and iOS use a trick to make it look like apps like always running in\nthe background: whenever the app is killed in the background, an app has an opportunity to save a small amount of data \nthat can be used to restore the app to a state, so that it _looks_ like the app was never killed.\n\nFor 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,\nthe OS may decide that there's not enough resources to keep the app running and will kill the app. By default, Flutter does not \nrestore any state when relaunching the app after that phone call, which means that whatever the user has entered has now been lost. \nWorse yet, the app will just restart and show the home screen which can be confusing to the user as well.\n\n## Saving state\nFirst of all: the term \"state\" may be confusing, since it can mean many things. In this case _state_ means: the *bare minimum* \namount of data you need to make it appear that the app was never killed. Generally this means that you should only persist things like\ndata being entered by the user, or an id that identifies whatever was displayed on the screen. For example, if your app is showing \na shopping cart, only the shopping cart id should be persisted using this plugin, the shopping cart contents related to this id \nshould be loaded by other means (from disk, or from the network).\n\n### Integrating with Flutter projects on Android\nThis plugin uses Kotlin, make sure your Flutter project has Kotlin configured for that reason.\nNo other setup is required.\n\nNote that as of version 1.1.0, Flutter version 1.12 or up is required and you should [migrate your project](https://github.com/flutter/flutter/wiki/Upgrading-pre-1.12-Android-projects)\nbefore updating from an older version of this plugin. \n\n### Integrating with Flutter project on iOS\nThis plugin uses Swift, make sure your project is configured to use Swift for that reason.\n\nYour `AppDelegate.swift` in the `ios/Runner` directory should look like this:\n\n```swift\n   import UIKit\n   import Flutter\n   // add this line\n   import native_state\n   \n   @UIApplicationMain\n   @objc class AppDelegate: FlutterAppDelegate {\n     override func application(\n       _ application: UIApplication,\n       didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?\n     ) -\u003e Bool {\n       GeneratedPluginRegistrant.register(with: self)\n       return super.application(application, didFinishLaunchingWithOptions: launchOptions)\n     }\n\n     // add these methods       \n     override func application(_ application: UIApplication, didDecodeRestorableStateWith coder: NSCoder) {\n         StateStorage.instance.restore(coder: coder)\n     }\n\n     override func application(_ application: UIApplication, willEncodeRestorableStateWith coder: NSCoder) {\n         StateStorage.instance.save(coder: coder)\n     }\n   \n     override func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -\u003e Bool {\n         return true\n     }\n   \n     override func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -\u003e Bool {\n         return true\n     }\n   }\n```\n\n## Using the plugin\nThe `SavedStateData` class allows for storing data by key and value. To get access to `SavedStateData` wrap your \nmain application in a `SavedState` widget; this is the global application `SavedState` widget. To retrieve the `SavedStateData` \nuse `SavedState.of(BuildContext)` or use the `SavedState.builder()` to get the data in a builder.\n\n`SavedState` widgets manage the saved state. When they are disposed, the associated state is also cleared. Usually you want to \nwrap each page in your application that needs to restore some state in a `SavedState` widget. When the page is no longer displayed, the\n`SavedState` associated with the page is automatically cleared. `SavedState` widgets can be nested multiple times, creating nested \n`SavedStateData` that will be cleared when a parent of the `SavedStateData` is cleared, for example, when the `SavedState` widget is removed\nfrom the widget tree.\n\n## Saving and Restoring state in `StatefulWidgets`\nMost of the time, you'd want your `StatefulWidget`s to update the `SavedState`. Use `SavedState.of(context)` then call `state.putXXX(key, value)` to\nupdate the state.\n\nTo restore state in your `StatefulWidget` add the `StateRestoration` mixin to your `State` class. Then implement the `restoreState(SavedState)` \nmethod. This method will be called once when your widget is mounted.\n\n## Restoring navigation state\nRestoring the page state is one part of the equation, but when the app is restarted, by default it will start with the default route, \nwhich is probably not what you want. The plugin provides the `SavedStateRouteObserver` that will save the route to the \n`SavedState` automatically. The saved route can then be retrieved using `restoreRoute(SavedState)` static method. *Important note:* for\nthis to work you need to setup your routes in such a way that the `Navigator` will restore them when you [set the `initialRoute` property](https://api.flutter.dev/flutter/widgets/Navigator/initialRoute.html).\n\nAnother requirement is that you set a `navigatorKey` on the `MaterialApp`. This is because the tree is rebuilt after the `SavedState` is initialised. When\nrebuilding, the Flutter needs to reuse the existing `Navigator` that receives the `initialRoute`.  \n\n## FAQ\n### Why do I need this at all? My apps never get killed in the background\nLucky you! Your phone must have infinite memory :)\n\n### Why not save _all_ state to a file\nTwo reasons: you are wasting resources (disk and battery) when saving all app state, using `native_state` is more efficient as it only saves the bare \nminimum amount of data and only when the OS requests it. State is kept in memory so there are no disk writes at all.\n\nSecondly, even though the app state might have saved, the OS might \nchoose not to restore it. For example, when the user has killed your app from the task switcher, or after some amount of time when \nit 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 practice \nto respect that, in stead of _always_ restoring the app state.\n\n### How do I test this is working?\nFor both Android and iOS: start your app and send it to the background by pressing the home button or using a gesture. Then \nfrom XCode or Android Studio, kill the app process and restart the app from the launcher. The app should resume from the same \nstate as when it was killed.\n\n### When is state cleared by the OS\nFor Android: when the user \"exits\" the app by pressing back, and at the discretion of the OS when the app is in the background.\n\nFor iOS: users cannot really \"exit\" an app on iOS, but state is cleared when the user swipes away the app in the app switcher.\n\n## License\n```Copyright 2019 Little Robots\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flittlerobots%2Fflutter-native-state","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flittlerobots%2Fflutter-native-state","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flittlerobots%2Fflutter-native-state/lists"}