Check for Launching from Uilocalnotification in Swift

Detect if App was Launched From Tapping Local Notification Swift

Look in the options for your scene delegate willConnect method or (if there is no scene delegate) your app delegate willFinishLaunching method. This tells you how you got launched.

Detect if app was launched by opening a local notification on iOS10+

Make sure you're assigning your implementation of UNUserNotificationCenterDelegate to UNUserNotificationCenter.current() before your app finishes launching, as it says in the documentation.

Then you should be getting a call to your UNUserNotificationCenterDelegate's userNotificationCenter(_:didReceive:withCompletionHandler:) at app launch with the response object, which contains the original notification. For me, it happened some time after my application(_:didFinishLaunchingWithOptions:) was called.

How to determine whether the app is opened from NotificationCenter (Local Notification) or the app icon when app is killed

How can I know if the app is opened by pressing the notification and not the app icon

As you said, implement the UNUserNotificationCenterDelegate method didReceive. If the user tapped your notification, it will be called, launching your app if it isn’t running.

Detect if the app was launched/opened from a push notification

See This code :

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground )
{
//opened from a push notification when the app was on background
}
}

same as

-(void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification

How to check launchOptions in Swift?

You are unwrapping the launchOptions dictionary, which is frequently nil, in your arguments. Trying to unwrap a nil value will lead to a crash so you need to check that it is not nil before using the trailing exclamation point to unwrap it. The correct code is as follows:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
if let options = launchOptions {
// Do your checking on options here
}

return true
}

Launch app from local notification in iOS 10

I found a solution. I wrapped a delay around the notification broadcast. My AppDelegate now looks something like this. For selecting the notification centre in didFinishLaunchingWithOptions:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
let options: UNAuthorizationOptions = [.alert, .badge, .sound]
center.requestAuthorization(options: options) {
(granted, error) in
if !granted {
print("Something went wrong")
}
}
} else {
application.registerUserNotificationSettings(UIUserNotificationSettings(types: [.alert , .badge , .sound], categories: nil))
}
return true
}

In didReceiveNotification I select out iOS 10...

func application(_ application: UIApplication, didReceive notification: UILocalNotification) {
if #available(iOS 10.0, *) {
// different notification centre for iOS 10, see @available below
} else {
if (application.applicationState == UIApplicationState.inactive || application.applicationState == UIApplicationState.background) {
runAfterDelay(2.0) { // 2 second delay, not sure if needed but doesn't seem to hurt - runAfterDelay function is below
NotificationCenter.default.post(name: Notification.Name(rawValue: NSLocalizedString("ticker_notification_name", comment: "")), object: notification.alertBody)
}
} /*else {
// handle the local notification when the app is open, if needed
} */
}
}

and use @available option to select for iOS 10:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// Determine the user action
switch response.actionIdentifier {
case UNNotificationDismissActionIdentifier:
print("Dismiss Action")
case UNNotificationDefaultActionIdentifier:
print("Default")
runAfterDelay(3.0) { // 3 second delay to give observer time to load. 3 seconds is arbitrary. runAfterDelay function is below
NotificationCenter.default.post(name: Notification.Name(rawValue: NSLocalizedString("ticker_notification_name", comment: "")), object: response) // .body
}
case "Snooze":
print("Snooze")
case "Delete":
print("Delete")
default:
print("Unknown action")
}
completionHandler()
}

and the runAfterDelay function that gives the observer time to put its socks on:

func runAfterDelay(_ delay: Double, closure:@escaping ()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
}

I think that I did not have to make any changes with the observer - I don't see any changes in my revision history, it looks the same as the addObserver method in the original question.



Related Topics



Leave a reply



Submit