0

I have made the ExtensionDelegate my UNUserNotificationCenterDelegate and properly assigned it. I have my watchOS 3 app add a notification request, which triggers

userNotificationCenter:willPresentNotification:withCompletionHandler:

I have implemented the method as follows:

- (void) userNotificationCenter:(UNUserNotificationCenter*)center
        willPresentNotification:(UNNotification*)notification
          withCompletionHandler:(void(^)(UNNotificationPresentationOptions))completionHandler
{
    NSLog(@"ExtensionDelegate: willPresent!");

    completionHandler(UNNotificationPresentationOptionAlert);
}

The problem is that nothing happens. I'm debugging in Xcode 8.2 on a device running watchOS 3.1, and though this delegate method is triggered, and I can hit the breakpoint, no alert is shown. My content is as follows:

UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
    content.title = notificationType;
    content.subtitle = [NSString stringWithFormat:@"Subtitle: %@", notificationType];
    content.body = alertTitle;
    content.badge = @1;
    content.sound = [UNNotificationSound defaultSound];
    content.launchImageName = @"LaunchImage";
    content.userInfo = @{
                         @"notificationType" : notificationType,
                         @"count" : @(count)
                         };
    content.attachments = @[];
    content.categoryIdentifier = notificationType;

where notificationType is the NSString I set on my application's launch as follows:

// Register custom notification types
    UNNotificationCategory* cat1 = [UNNotificationCategory categoryWithIdentifier:@"Category1"
                                                                           actions:@[dismissAction]
                                                                 intentIdentifiers:@[]
                                                                           options:UNNotificationCategoryOptionNone];

    UNNotificationCategory* cat2 = [UNNotificationCategory categoryWithIdentifier:@"Category2"
                                                                            actions:@[dismissAction, yesAction]
                                                                  intentIdentifiers:@[]
                                                                            options:UNNotificationCategoryOptionNone];
    NSSet* categorySet = [NSSet setWithArray:@[cat1, cat2]];
    [center setNotificationCategories:categorySet];

Unfortunately, when the notification request is made, willPresentNotification comes and goes, the completionHandler gets called, and then the app just keeps on running in the foreground. No notification alert appears on screen. It doesn't appear in the drag-down dock on the watch face, either. What else do I need to do to have it appear, either on-screen then and there, or into the pull-down dock?

Here is a visual example of what I'd expect to see on top of the app, or flush-top with the the top of the screen,with the app running below it. The banner can be even thinner than shown here:

Simple watchOS Notification

Erika Electra
  • 1,854
  • 3
  • 20
  • 31
  • Have you request permission to send a notification? From watch programming guide: Before the system can post alerts or play sounds for your app’s notifications, your Watch app or iOS app must request authorization to interact with the user. You do this by calling the requestAuthorizationWithOptions:completionHandler: method of the shared UNUserNotificationCenter object. – lostAtSeaJoshua Feb 14 '17 at 17:39
  • No, I requested permission on startup and got it at startup. I just need to send the actual alert itself. Like a banner on the top of the watch screen that shows up, then disappears. Do we have to create that as a WKInterfaceView (or whatever) ourselves? – Erika Electra Feb 15 '17 at 00:30
  • What is unclear to me is, when the delegate's willPresentNotification is called, what are we supposed to do to actually show the notification? I don't need flashy custom behavior like changing UI -- I just need the small banner that shows (some designers call it a "pancake" or a "toast") at the top of the watch screen, with the app icon and a single line of text. "Goal achieved!" or whatever. This is the kind of notification I would see in the swipe-down menu on the clock face for example; I just need to show that. Do I have to code that from scratch? Seems like we don't get it for free. – Erika Electra Feb 15 '17 at 00:33

1 Answers1

0

Related question, but for iOS: Displaying a stock iOS notification banner when your app is open and in the foreground?

I have been trying the same thing on the watch and get the same (non-displayed notification) result. One note, in case it helps others, is that we have to ask for the same permission as we return in the completion handler. For example, if we want to show Alert notifications, we have to use the two corresponding values as shown below. As the OP noted, we have to set ourself as the notification center delegate.

(BTW, if I've got any errors here, please point them out - mine is not working yet either).

The following code is in the watchkit extension delegate.

- (void)applicationDidFinishLaunching {
    // ...
    // Register for, and request permission to send notifications
    UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
    center.delegate = self;
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert)
                      completionHandler:^(BOOL granted, NSError * _Nullable error) {
                          // Enable or disable features based on authorization.
                          NSLog(@"Got auth response: %d", granted);
                      }];
}

The above is successful only when I have the notification permissions set to "Mirror the iPhone". If I turn that off, my permissions request fails. A different problem, but please check the returned granted value and make sure it's true.

// Foreground notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
             withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
    // The method will be called on the delegate only if the
    // application is in the foreground.
    NSLog(@"Will present notification: %@", notification);
    // The following doesn't present the notification, though.
    completionHandler(UNNotificationPresentationOptionAlert);
}

The userNotificationCenter:willPresentNotification:withCompletionHandler method does get called, but I don't see a notification overlay, nor is there one in the notifications list.

Community
  • 1
  • 1
Buddhisthead
  • 329
  • 2
  • 12