1

Here is my situation:

  • I have an app that gives the user a notification every hour.
  • This notification is actionable, with a "Mute Until Tomorrow" button attached to it. This button is, as you might guess, supposed to reschedule notifications to begin again the next day.
  • Thus, I have a block of code that needs to execute when you press this button.

If the app is running in the background, I use this function in my FirstViewController.swift file:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)

If the app is running in the background, this works perfectly. However, if the app has been force-quit by the user, this does not work. According to this post, iOS will never relaunch the app after the user force quits it. Edit: Apparently pressing a button in an actionable notification counts as user interaction, and your app can run code in response to this.

So I changed my actionable notification button to bring the app into the foreground when it is pressed, thinking this would solve my issue. However, for some reason, the function above is not called when launching the app from the button when the app has been force closed.

My first thought was to fix this using this function in the AppDelegate:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

but based on this list of launch option keys from Apple, I don't see a key for "actionable notification button pressed" or anything similar to that.

How do I detect that my app has been launched from an actionable notification button after it has been force closed?

Update: According to this Apple documentation, "If you do not implement this method [the first one I've listed above], your app never responds to custom actions." If this is true and there is no other method that will catch this, what do I do? Is what I'm trying to do simply impossible?

Nick Foster
  • 164
  • 9

1 Answers1

2

Figured it out. I moved the method I was originally trying to use:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void)

from my FirstViewController to my AppDelegate. I also moved all the setup code:

UNUserNotificationCenter.current().delegate = self
let muteAction = UNNotificationAction(identifier: "muteActionID", title: "Mute until tomorrow", options: [])
let tutorialCategory = UNNotificationCategory(identifier: "muteCategory", actions: [muteAction], intentIdentifiers: [], options: [])
UNUserNotificationCenter.current().setNotificationCategories([tutorialCategory])

to the AppDelegate's didFinishLaunchingWithOptions method. The didReceive response method is now called when I press the actionable notification button, regardless of whether or not the app has been force closed or not. Better still, it even works without having the open the app in the foreground.

Nick Foster
  • 164
  • 9