Ignore push notifications when iOS app is in the foreground - ios

I have a fairly large iOS project. When the app receives a notifications while in the foreground, the notification is displayed in something that looks like an AlertView. I want to get rid of it. I have no idea if this is something I programmed myself a long time ago, or if one of the frameworks in the project (Parse, Onesignal, FBSDK) is doing this. My question is, how can I find out where that alert view is coming from, so I can remove that code. I have not implemented the willPresentNotification method anywhere (I have searched through the entire project). I do have a didReceiveRemoteNotification method, and even though that should only be called when a notification is tapped, I have tried commenting it out. I have also searched through the entire project for UIAlertView and UIAlertController, to no avail.

OneSignal SDK automatically uses the new UserNotifications Framework, when iOS10 is detected on device.
In this case, the AppDelegate method didReceiveRemoteNotification method not get called, instead methods in UNUserNotificationCenterDelegate get invoked, which is captured by SDK to record clicks/views.
OneSignal use callback to handle received Notification.
OSHandleNotificationReceivedBlock: Called when the app receives a notification while in focus only
OSHandleNotificationActionBlock: Called when the user opens or taps an action on a notification.
OSNotificationOpenedResult: The information returned from a notification the user received.
You can directly implement UNUserNotificationCenterDelegate methods to handling notification-related interactions in your app.

Related

UserNotifications related events

I am working with an iOS app using UserNotifications.
When the user taps on a notification, this method is fired:
userNotificationCenter(_:didReceive:withCompletionHandler:)
I want to know if there is a method called when the notification arrives, independently of when the user reacts.
Yes you can : https://developer.apple.com/documentation/usernotifications/unusernotificationcenterdelegate/1649518-usernotificationcenter
Of course the app has to be open for that. you can not execute code if the app is closed.
In some cases you can execute code if the app is in background but that required special authorisation.

Push notifications not working properly when the app is not active (killed)

I'm facing a problem with push notifications, I'm using Google Cloud Messaging,
My problem is that my app works with some cached data, and I refresh that cache with the data coming from push notificacions, so when the app is killed by the user (home button + swipe-up) and the app receive a push notification it doesn't call the method didReceiveRemoteNotification, so the app can't access to the payload of that notification and update the cached data.
So, is there a way to achieve this?
Only when the user taps the notifications and the app gets it through the application:didFinishLaunchingWithOptions method?
If the user opens the app by clicking the application icon I can't get the notificaton's payload?
PD: If the app is in foreground or background (not killed) it works perfectly
If you wish your app to receive the push notification even when it is killed, add the key "content-available":"1" to the push payload.
Look here
EDIT:
After digging some more, I found out that silent push (e.g content-available:1), does not wake the app if it was killed by the user:
However, the system does not automatically launch your app if the user has force-quit it
I must say, I can't really understand why the OS does not let my app wake up when silent push arrives when it's dead. What's the point then???
This is the expected behavior. didReceiveRemoteNotification will not be called if the user killed the app, unless your app has VoIP permissions.
In case of killed application. both application:didFinishLaunchingWithOptionsandapplication:didReceiveRemoteNotification:fetchCompletionHandler:are called. In the prior one. The key of notification either remote or local is passed in options parameter. And the later one is called in only case when remote notification. The process is explained in detail in Apple Docs Here. The snapshot is pasted here as well.
Handling an Actionable Notification
If your app is not running in the foreground, to handle the default action when a user just swipes or taps on a notification, iOS launches your app in the foreground and calls the UIApplicationDelegate method application:didFinishLaunchingWithOptions: passing in the local notification or the remote notification in the options dictionary. In the remote notification case, the system also calls application:didReceiveRemoteNotification:fetchCompletionHandler:.
If your app is already in the foreground, iOS does not show the notification. Instead, to handle the default action, it calls one of the UIApplicationDelegate methods application:didReceiveLocalNotification: or application:didReceiveRemoteNotification:fetchCompletionHandler:. (If you don’t implement application:didReceiveRemoteNotification:fetchCompletionHandler:, iOS calls application:didReceiveRemoteNotification:.)
Finally, to handle the custom actions available in iOS 8 or newer , you need to implement at least one of two new methods on your app delegate, application:handleActionWithIdentifier:forRemoteNotification:completionHandler: or application:handleActionWithIdentifier:forLocalNotification:completionHandler:. In either case, you receive the action identifier, which you can use to determine what action was tapped. You also receive the notification, remote or local, which you can use to retrieve any information you need to handle that action. Finally, the system passes you the completion handler, which you must call when you finish handling the action. Listing 2-8 shows an example implementation that calls a self-defined action handler method. Reference Apple Docs
Edit:
The user taps the default button in the alert or taps (or clicks) the app icon. If the default action button is tapped (on a device running iOS), the system launches the app and the app calls its delegate’s application:didFinishLaunchingWithOptions: method, passing in the notification payload (for remote notifications) or the local-notification object (for local notifications). Although application:didFinishLaunchingWithOptions: isn’t the best place to handle the notification, getting the payload at this point gives you the opportunity to start the update process before your handler method is called.
Reference: Apple Docs
When the app is killed and the push notification triggered contains some actionable button. When we click on a Action Button of Push Notification then:
The first delegate that is executed is:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
But in here the launchOptions are nil.
The second delegate that is executed is:
-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo completionHandler:(nonnull void (^)())completionHandler
In this the variable userInfo contains all the payload of the Push Notification. With the help of identifier we can identify which action was invoked and then perform our respective operations.
add target of notification service extension in your project it contains two methods upper one method call in killed time and add a key "mutable_content" : true in server side of your notification payload

APNS push working in foreground but not background

Is it possible to have foreground push come in, but not receive push notification when the app is in background?
I've had some users report this problem and was wondering what could be the cause. Maybe it's just confusion? Please enlighten me if anyone else had the same problem and if so what the cause was. Thank you!
Perhaps you could exclude the alert in the payload dictionary of the push. This might prevent the message from being displayed on the device you push to. You could however include a message in the dictionary using a custom key . If you have not registered for background fetch, then it should not update the content of your app when the app is in background. In the didReceiveRemoteNotification method of your App delegate you can create a UIAlertView to show to the user by referring to the custom key. I guess it depends on what actions you are trying to prevent when the user receives the push.
Since iOS 7.0, there is a new message that your UIApplicationDelegate can respond to when a push notification arrives while the app is in the background: In addition to the application: didReceiveRemoteNotification:, there is now a method application: didReceiveRemoteNotification: fetchCompletionHandler:.
The older method is only called while the app is in foreground or when the user slides the notification sideways on the lock screen. The new method with the additional fetchCompletionHandler: parameter is always called. Have a close look at the reference, which describes a few important details on how to respond to this message.

How to access last local notification if the user ignored the last alert on ios?

My app is in background, and the notification alert did show correctly and the badge number was increased by 1.
IF the user taps on the alert everything works fine and the delegate didReceiveLocalNotification is called.
But the user ignored the alert.
After a while when the user open my app again, the only delegate called is didBecomeActive.
How can I do something (show a UIAlertView for example), based on the last ignored alert?
iOS itself doesn't provide any method for that.
But you can simply do that:
While you are registering notification to iOS - write all notification data to a file.
On application start load notification file and all notification that expired (NSDate < now) - those are ignored notifications.
Before doing 2. you need to check if maybe someone came from a notification and delete it from your file.
It's kind of duplicating iOS notification management system which is not allowing to get a list of registered notification unfortunately.
Writing a notification to a file should be easy: it's already implementing NSCoding protocol.
As far as I know, if the notification is ignored, you can't recover it once you open the app again.
You'll need to check the service that pushed that notification to know if there's something new
Unfortunately, there is not a straight forward way to achieve it.
Possible workaround - If the user dismisses/ignored your push notification, your app could take a look at messages on your server and handle it the appropriate way.

How can I handle unread push notifications in iOS?

I have a iOS 5.1 application that registers to the APNS service to receive notifications. The register is successful and I receive the notifications correctly. The problem comes when I try to handle the notifications.
Once the application is running, the method didReceiveRemoteNotification in the AppDelegate is called correctly and so the notification is handled as intended. This, however, only happens when the application is running on the foreground.
However, when the application is running on the background or is simply stopped, that method is not called. I've read that you should add some lines to the method didFinishLaunchingWithOptions method to obtain the notification from the userInfo dictionary, and handle it. This works just fine, but ONLY when the application is opened by clicking on the notification at the Notification Center. This means that if you open the application by clicking on its badge, or simply by changing context if you were running it on the background, the app never realises that a notification came in. Additionally, if more than one notification was received, we can only handle one of them at once by clicking on the Notification Center, which is a pain :-)
Is there any way to read the pending notifications in the Notification Center? I know there is a way to flush them using the method cancelAllLocalNotifications but I haven't found a way to just read them. And I really need to handle all of them. I thought of implementing a communication protocol with the third-party notification server to retrieve the information again when the application comes to the foreground, but since the information is already in the operating system I would find it strange if it's impossible to access it somehow.
So, does anybody know a way to do it? Thanks in advance.
When a push notification arrives and the user clicks 'cancel', your app has no way to read that push notification again. You have to implement a separate functionality (most probably on server-side) to fetch a list of notifications sent to this device.
For example, if a chat functionality is provided in your app and you send chat messages via push notifications then you should also keep chat messages on the server. If a user clicks 'Cancel' on any push notification then that chat message will not be displayed on the iOS device. In that case when a app comes in foreground later, you make a call to the server and fetch all the past chat messages (sent via push notification).
Ok, So a possible solution would be to have another database table with the messages in with a 'read' flag and a messageID field? Which by default the read flag is NO, then when the app successfully reads this and displays, it updates the flag to YES?
And with only 256 bytes to play with, what sort of ID field length would be necessary?
Edit,
Executed this plan and its working successfully.

Resources