IOS Push notification for messaging app - ios

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.

Related

Is possible use silent push to wake up APP and get the VOIP call?

if My app works at background, can I use silent push to wake app and get the VOIP call?
I used "jpush" to post a silent push which can work when connecting my idevice with Xcode and run APP.
If my idevice doesn't run APP with Xcode, I can not receive the silent push at background (only receive at foreground.)
Is it possible to use silent push to wake up APP and get VOIP call?
Did I get something wrong??
Yes. If your application does VoIP calling then it's possible to use PushKit:
Overview
The PushKit framework sends specific types of notifications — such as VoIP invitations, [...] — directly to your app for processing. [...]
Unlike user notifications, which are supported by the UserNotifications framework, PushKit notifications are never presented to the user — they don't present badges, alerts, or sounds.
PushKit notifications offer the following advantages over user notifications:
If your app isn't running, the system automatically launches it upon receiving the notification. [...] For more information, see Local and Remote Notification Programming Guide.
Your app is given runtime to process the notification, even if it's running in the background.
[...]

How to remove new Notifications from banner?

Is there any way to handle remote notification payloads before they’re delivered and display in notification centre?
With push notifications of default type there is no way to filter out notifications if the app is not in foreground.
The possible solution to this is to use VoIP push notifications in conjunction with PushKit.
VoIP pushes are always waking up the application, however they are not presented to the user and don't modify app badge value, so it's up to the developer to show a local notification upon the received VoIP push and to deal with app badge.
There is a technique with additional silent push that for example Facebook is using, to delete notification on iOS device when the message has been read on desktop web site. It's described here: https://www.pushwoosh.com/docs/deletable-ios-push

Is a iOS silent notification received when the app is killed

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.

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

Resources