I want to start off by saying I think I am doing my notifications wrong so I am here asking for help as to how to do it the proper way.
My goal -- Show a notification to the user whenever my server pushes them out to the iOS devices. I want this to work even if the app is closed.
Currently, if I have my app open (in the foreground) or running in a sleep state (not active), my remote notifications will funnel into my app and I show a local notification based on the info sent to my app from the server. I do this by handling the DidReceiveRemoteNotification & ReceivedRemoteNotification methods. If one of those are called, I parse the notification message and create a local notification (UILocalNotification).
I do have the 'Remote Notifications' turned on in my plist file.
If it helps, here is the JSON of one sample message I am sending:{"aps":{"content-available":1,"sound":""}, "message":"Foo Message", "title":"Foo Title"}
I am unsure if this is the correct way to handle notifications because if my app is not running, I do not get notifications to show up when one of pushed out. I have done some reading on this and there is this talk of if your app is 'force closed' it will not receive the notification. Side note -- this seems like a stupid rule for iOS to have lol. I feel like if I were to force close GMail, I will still get notifications for a new email arriving. How do they do it?
Going forward...how do I setup my iOS project to show a notification to the user whenever my server pushes one out no matter the state of my application?
Ok, so I think this will help. Take a look at the documentation here.
The relevant bit is this:
Use this method to process incoming remote notifications for your app. Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, 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.
After reading this, I don't think you can conditionally handle this. Also, there is more here about "Configuring a Silent Notification". The interesting bit I found in there was this:
For a silent notification, take care to ensure there is no alert, sound, or badge payload in the aps dictionary. If you don’t follow this guidance, the incorrectly-configured notification might be throttled and not delivered to the app in the background, and instead of being silent is displayed to the user.
In your previous comment, you do have the content-available
key and you also have the sound
key. That might explain some issues you were having (even though it was empty, maybe just not include the key at all).
Answers
Bump. Still need some guidance on this please.
Hi @TravyDale,
While your app is not running, and it receives a push notification, I believe the OS handles displaying the banner. It will parse the json payload and display the message and title. There is a specific structure that a PN json message is, and I believe this is part of the reason why. You might want to simplify your message and test if it's working. Try this:
{"aps":{"alert":"Foo Message"}}
If the user taps on the banner displayed, the
AppDelegate.FinishedLaunching
method is called. TheNSDictionary
of options passed in will containUIApplication.LaunchOptionsRemoteNotificationKey
to let you know the app was launched because of a push notification. You can check for this and handle it accordingly for your app. i.e. Display an alert, navigate to a page, etc.@JohnMiller
Oh ok. That makes more sense. Thanks for the reply. Is there any way the app will get notified when the push notification comes (while it is closed)? I was working on a solution that lets the user disable notifications at certain times of the day. If the app doesn't get notified when a notification comes through, then I can't conditionally show/suppress the notification.
@TravyDale,
Yes, this is handled by the OS and it obeys whatever settings your user has allowed for the app. i.e. Badges, Sounds, Banners, etc. These are what you request permission for. Typically the code looks like this:
@JohnMiller
So I have this (see below....similar to yours but not exact) and my app does not get opened up and get told of a notification. As in, it isn't opened or sleeping. It is completely closed. If I have the alert in my payload, I do get the notification, but I want to see if my app will be able to conditionally choose whether to show or suppress that notification before it gets shown to the Notification Center. Hope that makes more sense.
I have tried different flavors of my notification payload to get it to work and have failed. I do have both methods overridden: DidReceiveRemoteNotification & ReceivedRemoteNotification.
@TravyDale,
Ok, so I think this will help. Take a look at the documentation here.
The relevant bit is this:
After reading this, I don't think you can conditionally handle this. Also, there is more here about "Configuring a Silent Notification". The interesting bit I found in there was this:
In your previous comment, you do have the
content-available
key and you also have thesound
key. That might explain some issues you were having (even though it was empty, maybe just not include the key at all).Ok thanks. I did try it without the sound attribute because I did see that little bit about making sure other stuff is excluded. My app didnt get notified still. I am guessing I am unable to do what I am trying to achieve since the OS wants to process the notifications rather than the app processing them.
I also got confused by this:
I understood that as the device never getting the notifications. However, it seems you were always getting the notification, just not getting the
FinishedLaunching
orDidReceiveRemoteNotification
method call as you were expecting. I hope we've cleared up any confusion.That is correct. I am a bit surprised there isn't a way to have the app notified even if it isn't running. Kinda like you can do with Android and having a broadcast listener.
@JohnMiller The documentation you linked to with the following section :-
Does not clearly state which method it is referring to. For example, "Use this method to process incoming remote notifications for your app." - What method is this?
Thanks
Paul Diston
@PaulDiston,
Sorry for the confusion. It's referring to
application:didReceiveRemoteNotification:fetchCompletionHandler:
. It's noted under theDeclaration
paragraph, slightly above the blurb I quoted. The link is a little tricky because it's expanded the section under that method to see the text.That translates to this method:
Hi
From Apple Docs
Instead of using this method, create a delegate object that adopts the UNUserNotificationCenterDelegate protocol and implement the userNotificationCenter:willPresentNotification:withCompletionHandler: and userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler: methods. Assign this object to the delegate property of the singleton UNUserNotificationCenter object.
That method is only for when the app is open. What about if the app is closed or in background? What method can we latch onto to parse the data being received from notification?
No, application:didReceiveRemoteNotification: is called when the app is open. It corresponds to ReceivedRemoteNotification in Xamarin.
application:didReceiveRemoteNotification:fetchCompletionHandler: is called in the background/not running cases. It corresponds to DidReceiveRemoteNotification in Xamarin.
Can anyone tell me , when DidReceiveRemoteNotification get called exactly? Because i received notification when app is in background , but unable to get when app is killed...
You will not get notifications after the app is killed. You have to start the app again to begin receiving notifications. This is by design and well documented in the Apple notification programming guide.
Actually, apps like Messenger don't have a problem with this. After all, killing all the running apps is a common thing a lot of users do just to clean up the stack of running apps. I'd be surprised if that rendered their ability to react to incoming messages useless.
From the Local and Remote Notification Programming Guide:
Comparing the capabilities of first class applications (i.e. the built in apps) with those of 3rd party apps is unwise. First class apps are granted a lot more freedom than 3rd party apps.
When the app is running in the background, it works fine. The notification is receiving and the app triggered and event also getting.However, when the app is not running or manually killed app and a push notification is receiving but event not getting. So many developers saying that OS not trigger. I have doubt if not trigger event whenever user kills the app then WhatsApp display custom notification they decrypting message and showing notification, so I think event is possible some where missing Identifications is biggest job.
You can doubt all you want. I'm just quoting Apple's own documentation.
As to the events not triggering when they should, the most common problem is a failure to understand the breaking changes Apple keeps making in the API. Most of the tutorials and examples on the internet don't get updated to match those changes, so the problem continues.
Developing iOS applications absolutely requires that you stay familiar and current with Apple's documentation, whether you're using Obj-C, Swift, or C#. Non-Apple samples/tutorials must be checked against Apple's documentation before you decide to use the implementation in your app. There is more bad code and misinformation on the internet than not.
As to how WhatsApp does what it does, they are likely using notification extensions and message extensions among other things. That's just a guess since I don't have access to their code. ;-)
I could not receive notification when app are closed, i believe that DaveHunt is correct.
But, someone got it working?
I Disagree with Dave Hunt on this one. When I close my application I am able to get notifications through the following message. But so far ONLY ones sent through the firebase console, not through the proper ways my app sends these (sendbird, and webserver).
[Export("userNotificationCenter:willPresentNotification:withCompletionHandler:")]
public void WillPresentNotification(UNUserNotificationCenter center, UNNotification notification, Action completionHandler)
{
completionHandler(UNNotificationPresentationOptions.Alert | UNNotificationPresentationOptions.Sound | UNNotificationPresentationOptions.Badge);
}
This triggers when app is shutdown. When app is in background or foreground the DidReceiveRemoteNotification handles my other cases.
However the above method may not give me what I need, I'm just about to debug now to see if I can extract the needed data.
@DaveHunt
@JoshuaTanton > @JoshuaTanton said:
In my case I'm not able to receive notification for iphone x(but its working fine in iphone 5) when app is killed.
please help.
@DaveHunt @JoshuaTanton
kindly help
thanks