Use Push Notification payload when App launches via the Notification - ios

I was wondering how I can make use of the payload of a push notification, when the user is launching the app via opening that notification. Is this possible?
I want to implement an action which happens upon opening a notification, but this action requires part of the payload to work.
Cheers

Just implement the application(_ application:, didReceiveRemoteNotification userInfo:) in your AppDelegate. The userInfo is a JSON representation of your Push Notification (including the Payload).
Additionally you can check if the App is "inactive", wich means (in this case), that the User just came in to the App via this Push Notification
Example Code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
if (UIApplication.shared.applicationState == .active) {
// you just got a PushNotification, but the app is running currently
} else if (UIApplication.shared.applicationState == .inactive) {
// Do your work in here, the User just opened the App via the Push Notification
// check userInfo for the Payload
}
}

Related

iOS push notification: how to store push notification payload when application is kill or terminate in swift?

I am sending multiple push notification using firebase. My application getting all notification. Now how to store all push notifications data in user default when application is killed or terminate?
How to store all push notifications data when application is killed and the user click one push notification from all notification?
Your app is not getting invoked just with a push notifications. What you receive in the Notification tray is handled by iOS directly and the content of the push notification, specifically what is inside aps key of the Notification body is used to populate the content you see in the notification tray.
The app will not get invoked just because you received a push notification if the app is in suspended or killed state.
Unless of course your apns-push-type is set as background and content-available = 1 in your notification.
The call would go to
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
Where you may process the contents as required by the app.
To detect if the app was launched from a Notification,
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
if let dict = launchingOptions?[.remoteNotification]{
//App launched from Notification
if let userInfo = dict as? [AnyHashable:Any]{
//Do what your app requires with the notification using the userInfo.
}
}
}

iOS - Read the push notification once Received

I have 4 scenario
When the app is not Launched
Given the app was not Launched or Killed
When the push notification receive
And opened the app without tapping the notification
Then the app should capture the notification.
When the app is running in foreground
Given the app running in foreground
When the push notification receive
Then the app should capture the notification.
When the app is running in background
Given the app is running in background
When the push notification receive
And opened the app without tapping the notification
Then the app should capture the notification.
When the app is not Launched and cleared the notification
Given the app is not Launched or Killed
When the push notification receive
And user cleared the notification
And opened the app
Then the app should capture the notification.
The first 3 scenario works fine with the following code
The last scenario is not worked When the app is not Launched and cleared the notification
AppDelegate
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { requests in
for request in requests {
self.setNotification(userInfo: request.request.content.userInfo as NSDictionary)
}
})
}
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
setNotification(userInfo: userInfo as NSDictionary)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
setNotification(userInfo: userInfo as NSDictionary)
}
According to your query
When the app is not Launched and cleared the notification
Given the app is not Launched or Killed When the post notification
receive And user cleared the notification And opened the app Then the
app should capture the notification.
This is not possible for a Normal Push notification unless the user interacts with that notification. You may want to try Silent notifications, these are not shown in the UI but the control reaches the app and you can use the data/payload from there in your code.
When user clears the notification from bar, there is no way to fetch that information.
You could also try to add the same information that is being sent in the push within an API and call it once the user opens the app.
This link deals with all the detail involved. According to your implementation, you can try a combination of both.

How to handle Push on App not running state?

Is it possible to open the iOS App based on push notification content? I believe it's not possible. Is there any other way around? I believe we can go with the widget in iOS10, right? Please suggest some good solution?
Thanks!
Whenever your payload has content-available:1 your app will get called in the backgroundstate as soon as it arrives and will call application(_:didReceiveRemoteNotification:fetchCompletionHandler:). It will only not get called if the user killed the app manually. (This doesn't launch your app. It requires your app to be launched though)
Having that said if your app was terminated (by user) but the user taps on the notitication then your app is launched from didFinishLaunching...delegate method.
Whenever the user taps on push notification the application launches from not running state to running state the in AppDelegate
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
}
in this function you can check application is launch from push or application icon
var notification: [AnyHashable: Any]? = (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey] as? [AnyHashable: Any])
if notification != nil {
print("app received notification from remote\(notification)")
application(application, didReceiveRemoteNotification: notification)
}
else {
print("app did not receive notification")
}
Yes we can not open ios applications on push notifications but we can wake up the app on push notifications. Its called VOIP notification. You can have more info regarding this from below link https://github.com/hasyapanchasara/PushKit_SilentPushNotification

Apple Push Notification setting up Remote Notifications method overrides other methods

I have properly set up my app for Remote Notifications with the method
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
and it processes it correctly now every time the app receives an Apple Push Notification.
But my issue is that this method is being called in all instances now.
didFinishLaunchingWithOptions does not seem to be called anymore? Or the launchOptions is coming up empty?
Basically I used the didReceiveRemoteNotification as a catch all to process any incoming notifications which is my intended purpose, but then when I click the notification itself, it fires the didReceiveRemoteNotification again. Thus processing the notification twice, which I do not want.
So this is how I want my app to handle notifications:
Anytime a notification is received, would like to automatically process the notification in the background
When user clicks notification from outside app, to run a different method than the didReceiveRemoteNotification
When user is inside app, to run a different method than the other
Apple does not allow what you want. Push notifications work in the following way
1) When the application is not running, and the user clicks a notification, the application is launched and the payload of the notification is loaded in the function didFinishLaunchingWithOptions.
2) When the application is running in background, and the user clicks a notification, the application becomes active and the function didReceiveRemoteNotification is called. Now this function contains the payload of the notification.
3) When the application is running and a push notification is called, the function didReceiveRemoteNotification is called and this function contains the payload of the notification.
4) When the app is running in background or inactive and notification is received, nothing can be done with the notifications until the user clicks the notification

How to know a push message info if app is launched from background directly rather than from notification msg?

I have properly registered for the push notification.
Implemented following method to receive notification.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
Also used UIApplicationLaunchOptionsRemoteNotificationKey from func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool.
I'm able to receive notification when the app is active. I'm also able to see the notification if I open the app from the notification by selecting it from banner or alert.
But if app is not active, it could be alive or killed and if a notification arrives at that point. And I ignore the notification and open the app by directly selecting the app icon from the home screen, I'm not getting the notification information in the UIApplicationLaunchOptionsRemoteNotificationKey from func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject : AnyObject]?) -> Bool.
So what is the right way to handle this scenario? Should the app call server and get the recent messages it sent? Any help is much appreciated.
If the user will open you app directly from it's home screen, you would not get access to the push notification dictionary.
If you need the data sent in the push notification, so the proper way will be a server request as you suggested.
If user enter the app by click the icon or launch from the background, the push notification message can't deliver to you, the message is cached by system, the only way to get it is from notification center
Answering my question:
It is possible for the app in the background to receive push notification.
To do so send content-available in the aps dictionary of push notification.
Enable background mode of the app from the Background modes section of the Capabilities tab in your Xcode project.
Implement application:didReceiveRemoteNotification:fetchCompletionHandler: in the app delegate.
References:
See section 'Notification Payload' in https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
See section 'Using Push Notifications to Initiate a Download' in
https://developer.apple.com/library/prerelease/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
However if app is killed then the appdelegate's application:didReceiveRemoteNotification:fetchCompletionHandler: is not getting called.
According to Will iOS launch my app into the background if it was force-quit by the user? post on iOS8.0 it is possible to do it using PushKit. But I have not tested it. And also if VOIP is not used then I dont know if it is possible for app to receive push notification information if it is killed.

Resources