Local UserNotification is only triggered once on watchOS 3 b1

Hi,


I'm playing with the new UserNotification framework. On the iPhone, in iOS 10, mostly everything works great up until now and I have to say that I love this framework. On watchOS 3 on the other hand, it seems to be problematic. For example, a scheduled notification runs just once, after that it just doesn't get triggered anymore. Anyone else having this issue? Any workarounds for the time being?


The code I use is straightforward. (code that works on iOS 10 without any problems btw):


@IBAction func notifyButton() {

let content = UNMutableNotificationContent()

content.title = "Nice title"

content.body = "Great body... "

content.sound = UNNotificationSound.default()

/

let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 5, repeats: false)

let request = UNNotificationRequest.init(identifier: "id", content: content, trigger: trigger)

/

let center = UNUserNotificationCenter.current()

center.add(request) { (error) in

print(error)

}

}


(the requestAuthorization procedure is handled elswhere)


Tapping the button (and pushing the app to the background) delivers a notification in 5 secs. This only works the first time the app is installed on a simulator or actual watch. After that, tapping the button doesn't do anything. Even when I kill the app and relaunch it it doesn't work.

Replies

You need to specify a unique id to your UNNotificationRequest. Currently you are hard coding it to "id". With the UserNotifications framework, specifying the same id allows you to update a notification if it has not already fired. Once it has fired it seems to be a dead id. This is kind of confusing, and Apple should really not require an id and generate a unique id automatically if one is not specified. In any case, the way I have gotten around this is to generate a unique guid for each notification I schedule that I don't need to update:


func stringWithUUID() -> String { 
    let uuidObj = CFUUIDCreate(nil)   
    let uuidString = CFUUIDCreateString(nil, uuidObj)!
    return uuidString as String
}

// Then, when creating your request
...
let identifier = self.stringWithUUID()
let request = UNNotificationRequest.init(identifier: identifier, content: content, trigger: trigger)
...

Thanks! Wonder why no unique identifier is needed on the iPhone though. On iOS 10 it works with a hard-coded id.


Then again, isn't this the id that is used by the system to determine if a duplicate notification pushed by the iPhone should be displayed on the watch? In that case it is essential to use the same id on both the iPhone as the Watch. Seems to me that generating a unique id this way each time a notification is created is needlessly complex.


I think I file this as a bug. At least it should work consistently on all platforms. Anyway, thanks again, at least I can go on experimenting with this great new feature.

i find same issues too and same resolutions to fix it

Thank you this has helped me figure out why watch notifications only worked on sim reset.


Greg

This worked for me when pushing the Button without repeating.

How can you handle a repeating notification?


import WatchKit
import Foundation
import UserNotifications
class InterfaceController: WKInterfaceController {

  func stringWithUUID() -> String {
    let uuidObj = CFUUIDCreate(nil)
    let uuidString = CFUUIDCreateString(nil, uuidObj)!
    return uuidString as String
   }


  @IBAction func sendNotificationButton() {
    
      /
      let content = UNMutableNotificationContent()
      content.title = "Watch Notification Demo"
      content.body = "Notification Body Text!!"
      content.sound = UNNotificationSound.default()
      /
      let trigger = UNTimeIntervalNotificationTrigger.init(
        timeInterval: 60,
        repeats: true)
    
      /
      let identifier = self.stringWithUUID()
      let request = UNNotificationRequest.init(
        identifier: identifier,
        content: content,
        trigger: trigger
      )
  
  
      UNUserNotificationCenter.current().add(
      request, withCompletionHandler: nil)      /
  
  }

}