navigation_saver 0.2.1

Flutter navigation saver library (core module) #

This library will help to restore navigation stack after application kill.

Overview #

This is the core library and usually shouldn't be used directly. Please check general readme first. It should be used directly only if you would like have a full control of how routes are saved and restored.

How to use this library: #

  1. Be sure that you need exactly this core library. It has just base logic and all other big things like saving and restoring routes and arguments you will have to do by yourself.

Please check built value module (githib link or pub link) or json module (github link or pub link) for argument to map converting logic.

Please check shared prefreferences module (github link or pub link) for disk saving logic.

  1. If you still want to use this core library directly - include dependency: navigation_saver: ^0.2.0 - current module
  2. Create NavigationSaver class before your application widget:
void main() {
  final NavigationSaver _navigatorSaver = NavigationSaver(
    (routes) async => /* todo: add save code */,
    () async => /* todo: add restore code */,
  );

  runApp(MyApp(_navigatorSaver));
}

  1. Setup NavigationSaver as navigation observer and route generator:
class MyApp extends StatelessWidget {
  MyApp(this._navigationSaver);

  final NavigationSaver _navigationSaver;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: NavigationSaver.restoreRouteName,
      onGenerateRoute: (RouteSettings routeSettings) => _navigationSaver.onGenerateRoute(
        routeSettings,
        (
          RouteSettings settings,
          String routeName,
          Object routeArguments, {
          NextPageInfo nextPageInfo,
        }) => /* todo: generate your application widgets here. use `routeName` and `routeArguments` */,
      ),
      navigatorObservers: [_navigationSaver],
    );
  }
}
  1. This is it. Also you may want to add custom restoration widget that will be shown when library restore your navigation stack. This can be done by passing restoreRouteWidgetBuilder parameter in onGenerateRoute method.

How does core module work: #

  1. Saves application navigation stack to the class field by implementing NavigatorObserver

  2. Fires save routes callback when user stays on this route for some time.

  3. defaultNavigationRoute parameter is used when there is no routes to restore and this route will be pushed in that case. Default value is Navigator.defaultRouteName.

  4. restorePreviousRoutes method that will clear all current navigation stack and replace it with the restored state. This method should be called only in the application launch.

  5. onGenerateRoute method that will check passed route settings and decide the way how it should be handled. Currently we have only 2 ways:

    a. If the name of the route is NavigationSaver.restoreRouteName - library will push custom widget that will call restorePreviousRoutes. You may want to customize how does it look like by passing restoreRouteWidgetBuilder parameter.

    b. In all other cases library will check it the route arguments are from the restoration pushing or not.

    ba. If this route was pushed by the client code (not the restoration), then it will call NavigationSaverRouteFactory with passed settings, routeName = settings.name and routeArguments = settings.arguments. Also nextPageInfo will be null.

    bb. If this route was pushed by the restoration logic, then it will call NavigationSaverRouteFactory with passed settings, routeName = settings.name and routeArguments = restoredRouteArguments (note that after the restoration settings.arguments will have RestoredArguments type (See RestoredArguments). Also nextPageInfo will NOT be null if there is any next route above this one. This may be usefull if you need a result of the next route. See [how should I get a result of the next route after the kill].

RestoredArguments #

Flutter has a great feature in the navigation - you can wait for the next page result by using await keyword. And because when we restore the navigation stack we want to keep this ability we restore all routes with the new argument (RestoredArguments) class. This class has 2 fields: real page arguments and the next page information (NextPageInfo). See what can you do with it bellow.

How should I get a result of the next route after the kill (NextPageInfo class)

Imagine you had a stack of widgets A -> B. And widget A was waiting for result of B. Usually you do this by using such code:

  final result = await Navigator.of(context).pushNamed(
    "/next",
    arguments: SomeArgs(),
  );
  // do some work with the result

After the restoration logic the widget stack will be the same: A -> B. But there will be a big difference: widget A has never started the widget B - we did this in our library. But if you still want to get the result from B, you will need to use NextPageInfo class.

One of the best usage if this class:

  1. Save nextPageInfo field in your widget class:
class AWidget extends StatefulWidget {
  AWidget({
    Key key,
    this.nextPageInfo,
  }) : super(key: key);

  final NextPageInfo nextPageInfo;

  @override
  _AWidgetState createState() => _AWidgetState();
}
  1. Check it in the initState method and if there is some nextPageInfo - listen for it:
  @override
  void initState() {
    super.initState();

    if (null != widget.nextPageInfo) {
      switch (widget.nextPageInfo.routeName) {
        case '/next':
          awaitNextPageResult(widget.nextPageInfo.resultFuture);
          break;
      }
    }
  }

  Future<void> awaitNextPageResult(Future resultFuture) async {
    final result = await resultFuture;
    // do some work with the result
  }
  1. Also you may want to rewrite initial B widget initialization code:
  awaitNextPageResult(
    Navigator.of(context).pushNamed(
      "/next",
      arguments: SomeArgs(),
    ),
  );

[0.2.1] - 16.12.2019

  • Add ability to start/stop saving logic.
  • Add better error handling and logging.

[0.2.0+3] - 16.12.2019

  • Read.me update

[0.2.0+2] - 25.11.2019

  • Read.me update

[0.2.0+1] - 25.11.2019

  • Read.me update

[0.2.0] - 25.11.2019

  • Read.me update

[0.1.0+3] - 25.11.2019

  • Read.me update

[0.1.0+2] - 25.11.2019

  • Read.me update

[0.1.0+1] - 25.11.2019

  • Read.me update

[0.1.0] - 25.11.2019

  • Add example project

[0.0.1+1] - 25.11.2019

  • Add docs

[0.0.1] - 22.11.2019

  • Initial release.

example/README.md

Flutter navigation saver library example (built value module) #

This library will help to restore navigation stack after application kill.

Overview #

This example shows how to use our library with a combination of built value.

How to use our library is located here

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  navigation_saver: ^0.2.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:navigation_saver/navigation_saver.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
50
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
75
Learn more about scoring.

We analyzed this package on Feb 21, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.7.1
  • pana: 0.13.5
  • Flutter: 1.12.13+hotfix.7

Health suggestions

Fix lib/navigation_saver.dart. (-0.50 points)

Analysis of lib/navigation_saver.dart reported 1 hint:

line 63 col 43: Close instances of dart.core.Sink.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0 <3.0.0
flutter 0.0.0
pedantic ^1.7.0 1.9.0
Transitive dependencies
collection 1.14.11 1.14.12
meta 1.1.8
sky_engine 0.0.99
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies
flutter_test