Is a iOS silent notification received when the app is killed - ios

when sending a background push with "content-available": "1", to an app that is killed by the user, the application is not launched into the background mode and the application:didReceiveRemoteNotification:fetchCompletionHandler: is not called as the Apple doc say:
Use this method to process incoming remote notifications for your app. [...]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.
My question is: Is there is any way to access this silent push payload the next time the user starts the application?
I tried using the launchOptions of the didFinishLaunchingWithOptions method but they do not contain the push payload.
NSDictionary *userInfo = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
My use case is that I rely only on the push channel to receive data to the app but the app cannot pull them.

Short answer is: no, you cannot.
You also won't be able to use VoIP pushes, the only option would be to use regular pushes with a push notification service extension. Share a keychain between your app and this extension, save the push payload in the keychain when receiving a notification and retrieve it with your app when it enters foreground.
Downside is you will need to present a visual notification to the user, but it can be silent, and you can choose to present whatever text you want (the best option will depend on what your app does and what's the purpose of this notification).

You may use a VoIP Push message, see here:
Voice Over IP (VoIP) Best Practices
There are many advantages to using PushKit to receive VoIP pushes:
[...]
Your app is automatically relaunched if it’s not running when a VoIP push is received.
[...]
Be aware, that your app must have background mode with VoIP capability enabled, which may be an issue for app store approval if misused.

Looking at the documentation, it seems like you should implement this method:
optional func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
Within that method, write your code to store the payload (userInfo). Maybe store it in the userDefaults temporarily. Then when the application launches, check to see if the payload is available.

Related

IOS Push notification for messaging app

I am working with a messaging app and the app needs to receive the notification from the server (chat message). I am facing the problem when receiving the silent notification, most of the notification can’t received by the device, the scenario as below:
iOS 10 – Bring the app into background and push the silent notification, all notification can receive by the device.
iOS 11 – Bring the app into background and push the silent notification, device only can receive first 10 notifications and the rest of the notification disappear, I try to reboot the device and put the app into the background, able to receive another few notification and after that all not receive again.
Both iOS 10 and 11 – Kill the app and push the silent notification, all the notifications not receive.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
logging(cls: self, mod: "APP", msg: "Did receive remote notification")
}
I try the Whatsapp push notification, even I kill the app and turn off the background app refresh in setting, all the notification still come in, I’m curious how Whatsapp handle the push notification?
How do I solve this notification issue?
Ideally you should use XMPP server base for live chat.
XMPP server has RTC ( Real time communication ) protocol, where 2 or more parties can connect, exchange document, live chat, video call, audio call etc.
You can also integrate websocket, for knowing user is online / office and other activities.
Integrating apple push, is not a 100% solution for live chat app like whatsapp, facebook messager, skype etc.
Get more information about Pushkit
From iOS 8, Apple introduced a new kind of push notification service called VoIP push. VoIP push is provided by the Apple's PushKit framework.
Normal push notification service has the following drawbacks,
Delivery: Apple doesn't promise a delivery time or priority.
Need permission to send push: Not all users understand that they need to allow it to receive calls.
The app doesn't know about a push until the user decides to act on the push.
Apple might throttle your push messages if you send too many.
Now coming to PushKit framework,
The benefits of PushKit framework are,
You don't need to allow push; it works without the user knowing about it.
Apple promises to deliver these push notifications high priority.
Your push notifications won't get lost.
You have total control over push notifications.
So, for messaging apps like yours, the usage of PushKit framework is recommended. Here is a tutorial on Github which explains how to implement PushKit in your apps.

APNS: Receive silent Remote Notification if app was force quit

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.

WatchKit 2.0 Detect When APNS Is Received

I am creating an Apple Watch application which has a chat feature. I would like to update the chat conversation whenever the watch app is running and an APNS message is received. I know in the AppDelegate, the function
application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
can be used, but that's only when the device application is running in the foreground, not background. In the WKUserNotificationInterfaceController, there is the function didReceiveRemoteNotification, but that is only used when using a Dynamic Notification. Is it possible to have the watch application process a remote notification that is received when not using Dynamic Notifications and is running in the foreground?
When creating a WatchKit app, and using APNS, there's few things you need to know about how a push notification actually work on the Watch side.
1) It's the iOS system which choose wether or not the notification is handled by Watch, based on user activity (iPhone locked/unlocked; Watch is used/not used...).
When one of your app’s local or remote notifications arrives on the user’s iPhone, iOS decides whether to display that notification on the iPhone or on the Apple Watch. See Doc Apple
2) For the iOS side you can handle all your notifications in didReceiveRemoteNotificationapplication(_:didReceiveRemoteNotification:fetchCompletionHandler:) ==> you can check wether or not your app is in foreground + handle silent notifications.
3) There is two distinct entry points for notifications on the Watch side:
As you said, there's theWKUserNotificationInterfaceController which is called when your WatchKit app is not used.
And there's didReceiveRemoteNotification(_:) in your ExtensionDelegate class, which is called when your WatchKit app is running. See here for complete documentation.
If you need to update your app while it's running, through APNS, you should handle it in this last method ;)
Hope it'll help you!

iOS background fetch only working with debugger

I've been looking at this for a few days now and making no progress. I've developed a small test iOS (9.2.1) app that receives push notifications from the Azure Notification Hub. Everything appears to work fine, including the background notification push so long as the app is launched via xcode and is in debug mode.
Every notification I receive via the following callback just writes a file to the documents folder on the device. If I use xcode device explorer, I can see these files appearing
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
makefile(random file name based on timestamp);
completionHandler(UIBackgroundFetchResult.NewData);
}
I have also enabled the following modes in the UIBackgroundModes section of the plist file
fetch
remote-notification
The paypload that I send to the ANS server is:
"aps":{ "sound":"default", "content-available":1 }
Like I have mentioned above, so long as the app is running via xcode, I can press the home button, but it into the background and it will receive the push data fine. However, if I disconnect the USB cable it will stop receiving the background push events.
It's worth noting that the in-built OS notification does appear. Does anyone know what could be the problem here?
EDIT
If I launch the app via xcode, unplug the USB, send the notification - nothing happens. As soon as i reconnect to xcode it comes in and the code is run! Is this something to do with certifications (development / production)
The content-available key indicates iOS should treat this as a silent notification. Silent notifications are silent - they do not show an alert, badge, or play a sound.
A notification payload that contains both the content-available key and user-facing features like a sound or alert may be treated as either. The behavior is undefined - a notification should be silent or not, not both.
Silent notifications are handled by application(didReceiveRemoteNotification:fetchCompletionHandler), not application(_:didReceiveRemoteNotification:). It's possible that when your app does not seem to be getting the notification that iOS is calling this method.
In your case, you may also be getting throttled by iOS. If silent notifications are received too frequently, if you app uses too many resources handling them, etc. iOS will delay delivery of the notification. It will not delay them when launched from Xcode.
Your silent notification should not include a sound. Make that a separate notification, or try playing a sound in the background from inside your app.
Check the rate you are sending silent notifications to your app. At most send 2 an hour.
Verify that your silent notification handling code does not use excessive CPU, memory, or energy. Target using 15mb or less when handling the silent notification. Also make sure the fetchCompletionHandler block is called with 30 seconds of iOS calling application:didReceiveRemoteNotification:fetchCompletionHandler

Execute code in background when push notification is received

I'm trying to find out what is actually possible on iOS when it comes to background tasks.
I have an app which is running in the background and tracking location changes on the device.
Now, is it possible to send a push notification to the device and have the device send the current location to a server without needing the user to open the app so it runs in the foreground?
I know this question is a bit old but I'm answering for those who, like me, arrived here long after the question was asked.
Now, is it possible to send a push notification to the device and have the device send the current location to a server without needing the user to open the app so it runs in the foreground?
Yes. You can now do that. I'm currently doing something pretty similar in my app. There are some other SO questions that now correctly state this. This is one
Basically, you have to enabled Background Execution for Remote Notifications. You can do this in XCode by going to your app's target. Open the Capabilities tab enabling the Background Modes feature and checking the Remote Notifications item in the checklist. (I'm assuming you already have enabled the Push Notifications feature).
With this the code you use to handle notifications in foreground will also serve you in background as
the application:didReceiveRemoteNotification:fetchCompletionHandler method will be called while your app is in background.
Here's a sample code in Swift 3.0:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
You may wanna check out this SO question (and accepted answer) about how to handle network request in background. Background request not execute Alamofire Swift
Check out the docs about Background Execution. Particularly the section about Push Notifications
Unfortunately I don't think so. When your app is in a suspended (freezed) state, push notifications are managed by SO, users need to reopen the app. They other way around is to create local notification for significant changes, when the notif arrives your app has a minimum amount of time, it will be not enough to post data, but you can study something. I will suggest you to read this question it talks about bluetooth and geolocation link
It's impossible. This OS has one principle —— user should know what you(your app) have done. When your app is suspended,your push message will be received by the notification center.The only way let your app know this thing happened is to launch your app through the notification center.so.....

Resources