Skip to content

Commit

Permalink
Additional documentation on handling repeated notifications on iOS
Browse files Browse the repository at this point in the history
  • Loading branch information
MaikuB committed Apr 28, 2018
1 parent d8da090 commit a1743d1
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 4 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ Note that with Android 8.0+, sounds and vibrations are associated with notificat
By design, iOS applications do not display notifications when they're in the foreground. For iOS 10+, use the presentation options to control the behaviour for when a notification is triggered while the app is in the foreground. For older versions of iOS, you will need update the AppDelegate class to handle when a local notification is received to display an alert. This is shown in the sample app within the `didReceiveLocalNotification` method of the `AppDelegate` class. The notification title can be found by looking up the `title` within the `userInfo` dictionary of the `UILocalNotification` object

```
#import <flutter_local_notifications/FlutterLocalNotificationsPlugin.h>
...
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if(@available(iOS 10.0, *)) {
Expand Down Expand Up @@ -243,6 +247,15 @@ By design, iOS applications do not display notifications when they're in the for

In theory, it should be possible for the plugin to handle this but this the method doesn't seem to fire. The Flutter team has acknowledged that the method hasn't been wired up to enable this https://github.com/flutter/flutter/issues/16662

Also if you have set notifications to be periodically shown, then on older iOS versions (< 10), if the application was uninstalled without cancelling all alarms then the next time it's installed you may see the "old" notifications being fired. If this is not the desired behaviour, then you can add the following to the `didFinishLaunchingWithOptions` method of your `AppDelegate` class.

```
if(![[NSUserDefaults standardUserDefaults]objectForKey:@"Notification"]){
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"Notification"];
}
```

## 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.
4 changes: 2 additions & 2 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ PODS:
- Flutter

DEPENDENCIES:
- Flutter (from `Pods/.symlinks/flutter/ios`)
- Flutter (from `Pods/.symlinks/flutter/ios-release`)
- flutter_local_notifications (from `Pods/.symlinks/plugins/flutter_local_notifications/ios`)

EXTERNAL SOURCES:
Flutter:
:path: Pods/.symlinks/flutter/ios
:path: Pods/.symlinks/flutter/ios-release
flutter_local_notifications:
:path: Pods/.symlinks/plugins/flutter_local_notifications/ios

Expand Down
2 changes: 1 addition & 1 deletion example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
);
inputPaths = (
"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/.symlinks/flutter/ios/Flutter.framework",
"${PODS_ROOT}/.symlinks/flutter/ios-release/Flutter.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
Expand Down
5 changes: 5 additions & 0 deletions example/ios/Runner/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ @implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// cancel old notifications that were scheduled to be periodically shown upon a reinstallation of the app
if(![[NSUserDefaults standardUserDefaults]objectForKey:@"Notification"]){
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[[NSUserDefaults standardUserDefaults]setBool:YES forKey:@"Notification"];
}
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
Expand Down
3 changes: 2 additions & 1 deletion ios/Classes/FlutterLocalNotificationsPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ + (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
[registrar addMethodCallDelegate:instance channel:channel];
}


- (void)initialize:(FlutterMethodCall * _Nonnull)call result:(FlutterResult _Nonnull)result {
appResumingFromBackground = false;
NSDictionary *arguments = [call arguments];
Expand Down Expand Up @@ -279,13 +278,15 @@ - (void) showLocalNotification:(NSNumber *)id title:(NSString *)title body:(NSSt
if(@available(iOS 8.2, *)) {
notification.alertTitle = title;
}

if(presentSound) {
if(!sound || [sound isKindOfClass:[NSNull class]]){
notification.soundName = UILocalNotificationDefaultSoundName;
} else {
notification.soundName = sound;
}
}

notification.userInfo = [self buildUserDict:id title:title presentAlert:presentAlert presentSound:presentSound presentBadge:presentBadge payload:payload];
if(secondsSinceEpoch == nil) {
if(repeatInterval != nil) {
Expand Down

0 comments on commit a1743d1

Please sign in to comment.