I am trying to receive silent push notification when the app is totally off, but I'm not getting the push, what am I missing?
I added in split: Required background modes -> App downloads content in response to push notifications
I implement in the AppDelagate:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
completionHandler(UIBackgroundFetchResult.NewData);
JLToast.makeText("background").show()}
I send a push:
aps
{
content-available: 1
}
When the app is in background, I get the silent push notification,
but when the app is out of background (totally shot down),
I don't get the push.
What is missing?
As far as I know, silent push notification won't work in case the app is forced quit (by user). Consider 2 cases:
Force quit (by user, removing app from running apps list): app won't get notifications
Not force quit (Eg: when user restarts the phone, the app will be closed but it's not considered as being forced quit by user): the app will be launched in background mode and receive notifications
Related
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.
I have a strange case. My swift ios app is connected to Cloudkit. If the app is NOT running (background state), I receive my notifications badge and alert just fine, every time!
If the app is running, no notifications are received! I know it is not hitting the remote because I do this:
1. Adding a breakpoint to the didReceiveRemoteNotification event
2. Running xcode in a plugged iphone
3. NSLog("detected didReceiveRemoteNotification"), so final code look like this
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){
NSLog("detected didReceiveRemoteNotification")
}
I know the error is not coming from cloudkit or from APNS because I do receive alert banner and badge when the phone is in the background state.
Can you guide me to set this up properly for the Foreground state!?
I am running ios v9.3
UPDATE #1
I think the wording of the documentation is poor. It clearly says that both run on the foreground, which is what I cared about; nevertheless, the fix is more accurate than the documentation!
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.
You've implemented the wrong method. Implement:
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
As the docs explain:
Unlike the application:didReceiveRemoteNotification: method, ... the system calls this method when your app is running in the foreground or background.
I've read a lot of answers here and I can't find answers of this questions
How to stop badge, alert and sound from notifications when the application is not running ?
How to stop badge, alert and sound from notifications when the application is in Background?
in this function:
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
I've put completionHandler([]) without [.badge, .alert, .sound] and I still receive notifications in background when the app is runned.
Also I have function in my code that sends notification when somebody is typing to you and you see that he is typing to you when you are in-app, but when the application is not runned you are receiving notification with badge alert sound? How to prevent that?
PHP Code:
$body['aps'] = array(
'content-available' => 0,
'typingNewMessage' => 'true',
'senderId' => $your_id
);
Two things first: Are you using websocket/socket.io for the chat in your app? And as for notifications, have you set up remote notifications in background modes?
Background modes.
Read up on the docs for push notifications, it sounds like you're adding steps here, or missing some. Basically as kathayatnk mentioned, his method should give you what you want. So if you haven't activated remote background notifications:
To configure your app to process silent notifications in the
background
In the Project Navigator, select your project.
In the editor, select your iOS app target.
Select the Capabilities tab.
Enable the Background Modes capability.
Enable the Remote notifications background mode.
If this is done, you should receieve them in the background..
Also, you are using the wrong method for recieving background notifications in the background.. As stated in the same link above:
In iOS, the system delivers silent notifications by calling the
application:didReceiveRemoteNotification:fetchCompletionHandler:
method of your app delegate. Use that method to initiate any download
operations needed to fetch new data.
how i usually use it :
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
guard let aps = userInfo["aps"] as? [String:Any] else {
//handle something here..
return
}
//handle the content here...
}
You can also perform background tasks from inactive states here by playing with the return value of completionHandler. I suggest you read up on it too.
For your chat issue...
Clarify how you're performing this...
If you're using a websocket/socket.io architecture:
I would strongly recommend not using notifications to notify a user of anything with APNS when using a websocket. Websockets are very efficient and much quicker. Handling both can greatly complicate things. Stick to the socket approach, and use a method server side that checks if a user is still within the app. Something like a ping-pong method like here. Have that method switch to APNS delivery when the socket client ping method shows that the user has left the app or has closed it. This means, if the user is still in the app, but not in the conversation, stay with the ping approach but program the UI response differently (take FB Messenger or Snapchat's notification tabs for example).
If you are not using websockets/socket.io:
...Switch to websockets technologies or packages (depending on your server platform type) or socket.io or use firebase realtime chat services.
Let me know your setup like i asked earlier, but if youre doing all of this already and still getting the issues, then post your code.
Personnaly, i've used RawWenderlicht for APNS guides for over a year, good stuff if you ask me.
To silent push notification the payload should contain content-available key as:
{
"aps": {
"content-available": 1
}
}
Also, you need to enable Remote Notifications in Background Modes under Capabilities setting of your Xcode project.
Now your app will wake up in the background when it receives one of these push notifications.
didReceiveRemoteNotification will be called in AppDelegate whenever the push notification is received.
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
{
let aps = userInfo["aps"] as! [String: AnyObject]
if aps["content-available"] as? Int == 1
{
//Your code
}
}
For more on how to handle push notifications in foreground/background refer to: https://www.raywenderlich.com/156966/push-notifications-tutorial-getting-started
you can add silent push notifications (set content-available key appropriately) when sending pushes, like below.
//when you want the badge and sound
aps {
content-available: 1
}
//When you want silent notifications
aps {
content-available: 0
}
This will call the appropriate delegate method but wont display badge and sound
I am integrating Silent Remote notification in my application, all is working fine. But the issue is when my app is in killed state or not running state then no application delegate methods are getting triggered.
When I see in device log I can see:
"Springboard : High Priority Push: - App killed".
Can anybody please help me out.
I have implemented
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Swift.Void)
When app is in background and foreground state then above method is getting trigger.
I have enabled back ground fetch and Remote notification in the capabilities
Note:
I am sending silent push notification through terminal like this :
apn push <device_token> --certificate <path_of_pem_file> --payload '{"aps":{"content-available":1}}'
Thanks in advance
I am looking desperately for a way to receive silent remote notifications when the user has force quit his app.
I already experimented with this a while ago.
The only way to do that, was to remove the content-available flag. But then it wasn't a silent notification anymore. The main use case was to download additional content to the remote notification and only then schedule a local notification in turn.
As the new UNNotification Framework was introduced they also introduced the new Notification Service Extension which provides an elegant way to download content corresponding to a remote notification.
But there is still no way to do the same with silent notifications when the app is force closed. Or did I miss something ?
PS: Maybe it is a duplicate, but other threads do not respect the Notification Service Extension.
When app force closed. AppDelegate method:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
}
will not called. But if your json payload contain aps you will see instant message, after you swipe (or click on notification) method will be called.
You can look google and find table of difference silent and normal state and their work in other Application State
Finally I found the answer in localisation also discussed here:
Change language of alert in banner of Push Notification
I also use the new Notification Service Extension in combination to alter content before the notification is delivered.