How to get an array of all pending remote notification? - ios

Scenario:
My application is closed (not in background).
I received more than 1 remote notification.
I click on app icon (not on remote notifications).
How can I get array of JSON payload for received remote notification (more than 1).
Thanks in advance.

Unfortunately this is not possible.
You will only receive information about the notification that was used to open your app. If a user opens your app, and you have more than one notification, you will not be able to retrieve all of them from in the app.
Only one recent notification for a particular application is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded.
Apple Push Notification Service

APNs
Quality of Service
Apple Push Notification service includes a default Quality of Service (QoS) component that performs a store-and-forward function.
If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available.
Only one recent notification for a particular application is stored. If multiple notifications are sent while the device is offline, each new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification is referred to as coalescing notifications.
If the device remains offline for a long time, any notifications that were being stored for it are discarded.
Source
iOS
You can get a hold on only the last remote notification.

As iOS 10 it is possible
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
NSLog(#"msg getDeliveredNotificationsWithCompletionHandler count %lu", [notifications count]);
}];

You can do it like this
func getAllDeleveredPendingNotifications() {
let center = UNUserNotificationCenter.current()
center.getDeliveredNotifications { (notifications) in
print("pending notifications \(notifications)")
for info in notifications {
let userInfo = info.request.content.userInfo
print("UserInfo is \(userInfo)")
}
self.removeAllPendingNotification()
}
}

Related

Can UNUserNotificationCenter.getDeliveredNotifications() be used to retrieve user-directed push notifications

If a server sends a push notification to the user, but the user does not tap on that notification, can the app still determine that there was a push delivered to the handset and obtain the push payload using UNUserNotificationCenter.getDeliveredNotifications(), or is this method only for retrieving local notifications?
From the doc:
notifications
An array of UNNotification objects representing the
local and remote notifications of your app that have been delivered
and are still visible in Notification Center. If none of your app’s
notifications are visible in Notification Center, the array is empty.
So, yes it will return also push notifications not opened yet and visible in Notification Center.

iOS doesn't receive Push notification when the app is being killed

I have found similar questions on Stack Overflow, but none of them have cleared the point.
I am using Firebase Cloud Messaging for sending push notifications in my app. I am storing the messages received in a local database. When my app is active or in the background, my app is able to receive the notifications (delegate methods called properly) but if the app is being forced quit or not in the memory then also the device is receiving the notifications and sat in notification center but the none of the delegate methods called when the app is being launched by an icon. If a user clicks on Message in the notification center, then the app gets launched, but only the message clicked on is being received and not all of them (in the case of multiple notices have been received).
According to Apple - The system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.
But even if the user launched the app still not receive the notifications which were received and sat in the notification center.
Here are the points followed by the app:
My app has no VoIP functionality.
Content-available has been set to 1.
Has enabled to receive background remote notifications.
All notifications sent has been received and displayed in the notification center.
{
aps = {
alert = {
body = "Push Notification Test Message";
title = Push Notification;
};
badge = 1;
"content-available" = 1;
sound = default;
};
"gcm.message_id" = "0:1499340350307980%361a2e5b361a2e5b";
m = "Push Notification Test Message";
tag = m;
}
If the app is being forced quit or not in memory then your app will not receive silent notifications(i.e. Content-available set to 1).
Only push notifications are received in above conditions.
If user clicks on Message in notification center, then app gets launched and only that clicked the message will be received in delegate methods.You cannot access all the messages in the notification tray.
There is no way to get push notifications for the application if app is not running. This is restriction . You are only can get and clear local notifications. So the another way of resolving your problem is saving your notification on the backend when you send it. Then after launching app , you can get notifications list from the server , and match it with id . You can send any parameters that you want in notification playload.
Your app should not rely on the delivery of push notifications. Delivery of push notifications is not guaranteed, as you have found.
Even if your app isn't terminated you may not receive all notifications; For example if the device is in airplane mode and multiple notifications are sent, only the last one is delivered when the device comes back online.
Your app should check with the server for new messages when it is launched or when a notification is received in order to "catch up".
You can also consider including a message payload in your silent notifications. This will be displayed to the user if your app is terminated to prompt them to open your app.
You need to handle method for push notification when the application is open from a tap on any notification. As soon as you tap on notification application will awake and lunch it.
In didFinishLaunchingWithOptions, you need to put below condition:
if (launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey]) {
NSMutableDictionary *dic = [[NSMutableDictionary alloc] initWithDictionary:[launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey]];
}
It also called below method when notification is tapped:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))handler
{
}

List of push notifications

Can I get list of my app push notifications from native Notification Center app? When the my app starts, I want to show notifications which were received while my app is not running.
Actually you can get list of notifications with iOS 10
For this you have method in UNUserNotificationCenter
// Notifications that have been delivered and remain in Notification Center.
open func getDeliveredNotifications(completionHandler: #escaping ([UNNotification]) -> Swift.Void)
And do it like this
UNUserNotificationCenter.current().getDeliveredNotifications(completionHandler: { (notifications) in
// do what you whant with the notifications array
})
If you start your app from the icon, you can't get notifications
You can get one when you click the notification to start your app
If you don't want to miss any notification.
You can use Pushkit silent push notification.
Once you receive pushkit payload and your app you can schedule local notification and also keep in NSUserDefault.
Using silent push notification your app will be active in background even app is in terminated state. It will be active upto your local notification sound plays ( Max 30 seconds ). You can also keep data in SQLite in that duration.
Once you open app from icon or from notification you can check your NSUserDefauls or SQLite and do further things.
Note - With normal push notification, your app would get active in background or terminated state, so you can not write any code to keep data within app which cam along with push notification
Reference - https://github.com/hasyapanchasara/PushKit_SilentPushNotification
Let me know if further clarification is required.
as said by Tian:
there is no api to get a list of notifications your app missed.
no way.
you only get the one the user clicked to launch your app.

End-to-end tracking of ios push notification [duplicate]

I build xcode app that get push notification, the main problem is that the push notification is very critical for me.
so I want to check if the push notification is delivered to the device with the app installed, I understand that if the iphone dosn't have internet connecction / 3G the push notification is not getting to the device.
how can I check if the device get the notification or not?
how can I check if the APNS successful to deliver the push notification?
I want to send sms if the push notification is not deliver to the device so I think about the idea to get the notification event when it's open by the push notification, and to send request to my server so i can know if the push notification is successful deliver or not. the main problem is that the user need to open the app every time he get the notification and in the night it's a problem. so this option is not good for me.
I check the feedback server push notification but i don't find any info that I can get if the push notification is delivered or not
any idea??
With iOS7 you have a new method called
application:didReceiveRemoteNotification:fetchCompletionHandler:
which you probably could use for your task. From Apple's Docs:
Implement this method if your app supports the remote-notification background mode.
...
When a push notification arrives, the system displays the notification to the user and
launches the app in the background (if needed) so that it can call this method. Use this
method to download any data related to the push notification. When your method is done,
call the block in the handler parameter.
Unlike the application:didReceiveRemoteNotification: method, which is called only when
your app is running, the system calls this method regardless of the state of your app.
The short answer, you can't, since APNS is one way. However, since an app can execute arbitrary code upon receipt of a notification, you can use this to say, send an http request to your own server when the notification is recieved.
There are any number of reason why push notifications might not get delivered to your user, or might not be delivered in a timely manner. Apple does not provide any mechanism for you to query the status of a push notification that you have sent.
If your app is currently running on the user's device and the user is accepting notifications for your app, you can implement the following method in your app delegate. It would be called whenever a push notification is received and in this method you could send a request back to your server to indicate the message was received. However this will only work while the user is running your app.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
In general though, it sounds like you'e relying on push notifications for something you shouldn't. From Apple's Local and Push Notification Programming Guide:
Important Because delivery is not guaranteed, you should not depend on
the remote-notifications facility for delivering critical data to an
application via the payload. And never include sensitive data in the
payload. You should use it only to notify the user that new data is
available.
There is no way to find out whether the notification was delivered to the device or no. APNS is a one way service. If there is no internet connection on the device then the APNS server will hold the last notification for some period of time which is no specified by Apple. If a new notification is sent to APNS for delivery then the old notification data is lost and replaced by the new data if its undelivered. If the notification is delivered then also the old notification data is deleted on the APNS server.
Please go through the following link : Apple Push Notification
Hope this helps you...........
If you are using JAVAPNS to send the APNS notification, you can use the below:
List<PushedNotification> notifications =
Push.combined("alert", badge, "default", "cert.p12", "certpassword", true, deviceToken);
for (PushedNotification notification : notifications) {
if (notification.isSuccessful()) {
//Push is successful. Do your thing...
}
else {
//Push is not successful. Do your thing...
}
}

Preserving read push notifications

I was wondering if it's possible to keep the last 5 (for example) read notifications in the apple's notification center (the one that shows up when you swipe down near the top)
I've noticed that once you click on a notification and "read" it, it disappears from the list. Is this done programaticaly by the app, who sends the device a message that the notification has been read and it's ok to delete it, or is it done automatically by the device and you have absolutely no control on it.
One client said it saw an app that did this and kept the last 5 notifications there, regardless if they were accessed or not but so far I've found nothing to indicate that this is possible
Well, it's not a very complete answer, but one of my colleagues managed to make this work.
All he did was to stop using badge number for notifications. No badge number is set when a notification is received, and no badge number is set when a notification is read.
[edit]It seems that when you set the badge number to 0 after you receive the notification, iOS automatically clears the notification, this being an undocumented feature.
You can only "read" the notifications sent to your App, and only if the user explicitly used their "action" button to open your App. if that was the scenario you can use:
// Handle local notification if received
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey] != nil) {
NSLog(#"received a local notification = %#", [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]);
// Do something, save it..
}
// Handle remote notification if received
if ([launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey] != nil) {
NSlog(#"received a remote notification = %#", [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]);
// Do something, save it..
}
Or other alternatives (NotificationCenter etc) to read the notification when the app is opened with it and save it persistently.

Resources