From 1c5b1d20ec31eb6704c4ca7a9f1e86a7ba510e3c Mon Sep 17 00:00:00 2001 From: Michael Bui <25263378+MaikuB@users.noreply.github.com> Date: Fri, 24 Jan 2020 19:59:08 +1100 Subject: [PATCH] [flutter_local_notifications] expose NotificationAppLaunchDetails from main plugin again and add default behaviour when running on neither Android or iOS (#455) * Fix exposing NotificationAppLaunchDetails via main plugin and make methods a no-op on platforms other than Android and iOS * add null propagation when running on environment where platform is neither Android or iOS * return an instance of NotificationAppLaunchDetails when platform instance can't be detected and getNotificationAppLaunchDetails is called * default didNotificationLaunchApp to false * update readme on testing and update API docs on getNotificationAppLaunchDetails --- flutter_local_notifications/CHANGELOG.md | 9 ++++-- flutter_local_notifications/README.md | 2 +- .../lib/flutter_local_notifications.dart | 5 ++- .../flutter_local_notifications_plugin.dart | 31 ++++++++++--------- flutter_local_notifications/pubspec.yaml | 2 +- 5 files changed, 29 insertions(+), 20 deletions(-) diff --git a/flutter_local_notifications/CHANGELOG.md b/flutter_local_notifications/CHANGELOG.md index 7d6c1befc..df5643520 100644 --- a/flutter_local_notifications/CHANGELOG.md +++ b/flutter_local_notifications/CHANGELOG.md @@ -1,3 +1,8 @@ +# [1.1.3] +* Expose `NotificationAppLaunchDetails` via main plugin +* Retroactively updated changelog for 1.1.0 to indicate breaking change on moving to using platform interface +* Made plugin methods be a no-op to fix issue with version 1.1.0 where test code involving the plugin would fail when running on an environment that is neither Android or iOS + # [1.1.2] * Passing a null notification id now throws an `ArgumentError`. Thanks to PR from [talmor_guy](https://github.com/talmor-guy) * Slight tweak to message displayed with by `ArgumentError` when notification id is not within range of a 32-bit integer @@ -7,8 +12,8 @@ * [Android] Added ability to specify the notification category # [1.1.0] -* Updated plugin to make use of `flutter_local_notifications_platform_interface` version 1.0.1. This allows for platform-specific - implementations of the platform interface to now be accessible. +* **BREAKING CHANGE** Updated plugin to make use of `flutter_local_notifications_platform_interface` version 1.0.1. This allows for platform-specific implementations of the platform interface to now be accessible. Note that the plugin will check which platform the plugin is running on. + *Note*: this may have inadvertently broke some tests for users as the plugin now checks which platform the plugin is executing code on and would throw an `UnimplementedError` since neither iOS or Android can be detected. Another issue is that `NotificationAppLaunchDetails` was no longer exposed via the main plugin. Please upgrade to 1.1.3 to have both of these issues fixed * **BREAKING CHANGE** Plugin callbacks are no longer publicly accessible * **BREAKING CHANGE** [iOS] Local notifications that launched the app should now only be processed by the plugin if they were created by the plugin. diff --git a/flutter_local_notifications/README.md b/flutter_local_notifications/README.md index fe9f90107..d75283ef6 100644 --- a/flutter_local_notifications/README.md +++ b/flutter_local_notifications/README.md @@ -420,4 +420,4 @@ https://developer.apple.com/documentation/usernotifications/unnotificationsound? ## Testing -As the plugin class is not static, it is possible to mock and verify it's behaviour when writing tests as part of your application. Check the source code for a sample test suite can be found at _test/flutter_local_notifications_test.dart_ that demonstrates how this can be done. +As the plugin class is not static, it is possible to mock and verify it's behaviour when writing tests as part of your application. Check the source code for a sample test suite can be found at _test/flutter_local_notifications_test.dart_ that demonstrates how this can be done. If you decide to use the plugin class directly as part of your tests, note that the methods will be mostly a no-op and methods that return data will return default values. Part of this is because the plugin detects if you're running on a supported plugin to determine which platform implementation of the plugin should be used. If it's neither Android or iOS, then it defaults to the aforementioned behaviour to reduce friction when writing tests. If this not desired then consider using mocks. diff --git a/flutter_local_notifications/lib/flutter_local_notifications.dart b/flutter_local_notifications/lib/flutter_local_notifications.dart index 4282b71c9..cbb4d38ab 100644 --- a/flutter_local_notifications/lib/flutter_local_notifications.dart +++ b/flutter_local_notifications/lib/flutter_local_notifications.dart @@ -1,5 +1,8 @@ export 'package:flutter_local_notifications_platform_interface/flutter_local_notifications_platform_interface.dart' - show PendingNotificationRequest, RepeatInterval; + show + PendingNotificationRequest, + RepeatInterval, + NotificationAppLaunchDetails; export 'src/platform_specifics/android/styles/style_information.dart'; export 'src/platform_specifics/android/styles/default_style_information.dart'; diff --git a/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart b/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart index 5fc3d318c..ed8583e80 100644 --- a/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart +++ b/flutter_local_notifications/lib/src/flutter_local_notifications_plugin.dart @@ -10,6 +10,8 @@ import 'typedefs.dart'; import 'types.dart'; /// `FlutterLocalNotificationsPlugin` allows applications to display a local notification. +/// The plugin will check the platform that is running on to use the appropriate platform-specific +/// implementation of the plugin. The plugin methods will be a no-op when the platform can't be detected. class FlutterLocalNotificationsPlugin { factory FlutterLocalNotificationsPlugin() => _instance; @@ -33,6 +35,9 @@ class FlutterLocalNotificationsPlugin { /// Initializes the plugin. Call this method on application before using the plugin further. /// This should only be done once. When a notification created by this plugin was used to launch the app, /// calling `initialize` is what will trigger to the `onSelectNotification` callback to be fire. + /// + /// Will return a [bool] value to indicate if initialization succeeded. When running in environment that is + /// neither Android and iOS (e.g. when running tests), this will be a no-op and return true. Future initialize(InitializationSettings initializationSettings, {SelectNotificationCallback onSelectNotification}) async { if (_platform.isAndroid) { @@ -45,13 +50,15 @@ class FlutterLocalNotificationsPlugin { as IOSFlutterLocalNotificationsPlugin) ?.initialize(initializationSettings?.ios, onSelectNotification: onSelectNotification); - } else { - throw UnimplementedError('initialize() has not been implemented'); } + return true; } /// Returns info on if a notification had been used to launch the application. /// An example of how this could be used is to change the initial route of your application when it starts up. + /// + /// If the plugin isn't running on either Android or iOS then it defaults to indicate that a notification wasn't + /// used to launch the app. Future getNotificationAppLaunchDetails() async { if (_platform.isAndroid) { return await (FlutterLocalNotificationsPlatform.instance @@ -63,7 +70,8 @@ class FlutterLocalNotificationsPlugin { ?.getNotificationAppLaunchDetails(); } else { return await FlutterLocalNotificationsPlatform.instance - .getNotificationAppLaunchDetails(); + ?.getNotificationAppLaunchDetails() ?? + NotificationAppLaunchDetails(false, null); } } @@ -83,18 +91,18 @@ class FlutterLocalNotificationsPlugin { ?.show(id, title, body, notificationDetails: notificationDetails?.iOS, payload: payload); } else { - await FlutterLocalNotificationsPlatform.instance.show(id, title, body); + await FlutterLocalNotificationsPlatform.instance?.show(id, title, body); } } /// Cancel/remove the notification with the specified id. This applies to notifications that have been scheduled and those that have already been presented. Future cancel(int id) async { - await FlutterLocalNotificationsPlatform.instance.cancel(id); + await FlutterLocalNotificationsPlatform.instance?.cancel(id); } /// Cancels/removes all notifications. This applies to notifications that have been scheduled and those that have already been presented. Future cancelAll() async { - await FlutterLocalNotificationsPlatform.instance.cancelAll(); + await FlutterLocalNotificationsPlatform.instance?.cancelAll(); } /// Schedules a notification to be shown at the specified time with an optional payload that is passed through when a notification is tapped @@ -114,8 +122,6 @@ class FlutterLocalNotificationsPlugin { as IOSFlutterLocalNotificationsPlugin) ?.schedule(id, title, body, scheduledDate, notificationDetails?.iOS, payload: payload); - } else { - throw UnimplementedError('schedule() has not been implemented'); } } @@ -137,7 +143,7 @@ class FlutterLocalNotificationsPlugin { notificationDetails: notificationDetails?.iOS, payload: payload); } else { await FlutterLocalNotificationsPlatform.instance - .periodicallyShow(id, title, body, repeatInterval); + ?.periodicallyShow(id, title, body, repeatInterval); } } @@ -157,8 +163,6 @@ class FlutterLocalNotificationsPlugin { ?.showDailyAtTime( id, title, body, notificationTime, notificationDetails?.iOS, payload: payload); - } else { - throw UnimplementedError('showDailyAtTime() has not been implemented'); } } @@ -178,15 +182,12 @@ class FlutterLocalNotificationsPlugin { ?.showWeeklyAtDayAndTime( id, title, body, day, notificationTime, notificationDetails?.iOS, payload: payload); - } else { - throw UnimplementedError( - 'showWeeklyAtDayAndTime() has not been implemented'); } } /// Returns a list of notifications pending to be delivered/shown Future> pendingNotificationRequests() { return FlutterLocalNotificationsPlatform.instance - .pendingNotificationRequests(); + ?.pendingNotificationRequests(); } } diff --git a/flutter_local_notifications/pubspec.yaml b/flutter_local_notifications/pubspec.yaml index 0d49c361b..db40f91ca 100644 --- a/flutter_local_notifications/pubspec.yaml +++ b/flutter_local_notifications/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_local_notifications description: A cross platform plugin for displaying and scheduling local notifications for Flutter applications with the ability to customise for each platform. -version: 1.1.2 +version: 1.1.3 homepage: https://github.com/MaikuB/flutter_local_notifications/tree/master/flutter_local_notifications dependencies: