UNNotification (Local Notification) on watchOS 3 not showed

Hi guys

I’ve a problem with the UNNotification on watchOS 3 !

In watchOS 2 and iOS 9 to schedule a local notification I use WatchConnectivity

From watch I send a message to iPhone and the iPhone schedule the local notification

When the notification arrive with the iPhone locked the watch duplicate the notification and NotificationController in WatchKit Extension call the method

- (void)didReceiveLocalNotification:(UILocalNotification *)localNotification
                     withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler;

that show the notification on watch.

So in watchOS 3 i would like send and receive the notification directly from watch

some code

In watchKit Extension Target i add UserNotifications.framework

In ExtensionDelegate import the framework, add the UNUserNotificationCenterDelegate and request the authorization


#import "ExtensionDelegate.h"
#import <UserNotifications/UserNotifications.h>
@interface ExtensionDelegate()<UNUserNotificationCenterDelegate>{
}
@end
@implementation ExtensionDelegate
- (void)applicationDidFinishLaunching {
    /
    UNUserNotificationCenter *notifCenter = [UNUserNotificationCenter currentNotificationCenter];
    notifCenter.delegate = self;

    [notifCenter requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error){
   
        if( !error ){
            /
        }
    }];

}


Then in InterfaceController i schedule an UNNotification


- (IBAction)SendLocalNotification {
  
    UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
    content.title = [NSString localizedUserNotificationStringForKey:@“Test” arguments:nil];
    content.subtitle = [NSString localizedUserNotificationStringForKey:@“Local notification from Watch " arguments:nil];
    content.sound = [UNNotificationSound defaultSound];
    [content setValue:@YES forKeyPath:@"shouldAlwaysAlertWhileAppIsForeground"];
    UNTimeIntervalNotificationTrigger* timeTrigger = [UNTimeIntervalNotificationTrigger
                                                      triggerWithTimeInterval:10 repeats:NO];

    NSString *uuid = [[NSUUID UUID] UUIDString];
    UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:uuid
                                                                          content:content trigger:timeTrigger];
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];

    [center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
        if (!error) {
            NSLog(@" local notification scheduled”);
        }
    }];
}


(I've also update SendLocalNotification method after reading this post, but I 've not solved the problem)

in NotificationController import the framework and this is the code

#import "NotificationController.h"
#import <UserNotifications/UserNotifications.h>
@interface NotificationController()
@end
@implementation NotificationController
@synthesize label;
- (instancetype)init {
    self = [super init];
    if (self){
        /
        /
    }
    return self;
}
- (void)willActivate {
    /
    [super willActivate];
}
- (void)didDeactivate {
    /
    [super didDeactivate];
}
- (void)didReceiveNotification:(UNNotification *)notification
                withCompletion:(void(^)(WKUserNotificationInterfaceType interface)) completionHandler {
    /
    /
    /
    /
    /
    [label setText:notification.request.content.subtitle];
    completionHandler(WKUserNotificationInterfaceTypeCustom);
}
@end
In ExtensionDelegate i also implement the method to receive the notification when the app is in foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
    NSLog(@“notification arrived in foreground");

    completionHandler(UNNotificationPresentationOptionAlert|UNNotificationPresentationOptionSound);
}


It’s seem everything ok but ….

  • when the watch app is in background don’t receive the notification
  • when the watch app is in foreground the console print the log “notification arrived in foreground" but the notification isn’t shown


Where is the problem ?

What i’ve missed ?

I hope someone can help me !!

Thank you so much in advance !!

Vanni

Replies

I'm having the exact same problem! After the authorization was successful, I schedule my notification with the following code.


    var date = DateComponents()
    date.hour = 17
    let calendarTrigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
   
    var text = NSLocalizedString("notificationText", comment: "")
   
    let content = UNMutableNotificationContent()
    content.title = NSLocalizedString("notificationTitle", comment: "")
    content.body = text
    content.sound = UNNotificationSound.default()
    content.categoryIdentifier = "myCategory"
   
    content.setValue("YES", forKeyPath: "shouldAlwaysAlertWhileAppIsForeground")

   
    let request = UNNotificationRequest(
      identifier: identifier,
      content: content,
      trigger: calendarTrigger)
   
    UNUserNotificationCenter.current().add(request) { error in
      if let error = error {
        print(error)
        
      } else {
        print("Feeding Notfication was scheduled")
      }
    }
  

I also get no notification displayed when the App is running in fore- or background, but I get the log message.


Would be great if anyone could help us.


Best,
Klemens

It is a relief to know that I'm not alone ... Anyway I suspect that something need to be set in NotificationController , but I don't know what and how ... Help us Please Thanks so much Vanni

make sure you have a unique identifier everytime you schedule notification on watchos.

NSString *uuid = [[NSUUID UUID] UUIDString]; 
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:uuid content:content trigger:timeTrigger];


Thanks but I've already set a unic indentifier

I found two workarounds for this issue.


Note this is watchOS 3.1.


My code was similar to your code in SendLocalNotification method to add a request and wait for a notification which never came.


Method 1.

I thought maybe checking the authorization prior to each request might be necessary, so I wrapped the code you have in a block:


[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {

if (settings.authorizationStatus == UNAuthorizationStatusAuthorized) {

< code from SendLocalNotification >

};

}];


When I added this code, notifications started working correctly. I tried adding your code block into an operation, then adding to a serial queue. But that notifications did not work. So, its something to do with the queue that exists when the completion handler returns.


I found you can drop the if conditional, and it still works.


Method 2.


Starting with your same code, and not surrounding it with the code from Method 1., I dropped the completion handler in the addNotificationRequest message and set it to nil. Notifications started working fine.


I have no idea why adding a completion handler to the message interferes with the notifications, but it does.


I prefer Method 1. since it allows for checking for errors in the addNotificationRequest message.