I'm building a mobile chat app. I've configured OneSignal to send push notifications to my iOS device.
I plan to send push notifications to the user when a new message is received and the application isn't in the foreground (similar to how Facebook Messenger works).
I'm new to push notifications. I can imagine two solutions, neither of them elegant:
Solution 1: Send a push notification every time a message is sent. Then, if the app is open, ignore/swallow the notification. (Seems like a waste of resources).
Solution 2: Keep track of the app's state in my own database and only send a push notification if the app isn't in the foreground. (Seems overly complex).
What am I missing? What is the correct way to handle this?
Related
I have implemented AWS SNS push notification service.
We have an issue which is explained below :
Scenario :
We are trying to save the notification message we receive as a part of requirement.
When the app is killed (swipe out from recent apps) we are able to receive notification, also we are able to save the notification message when we open the message directly from the notification panel it works fine,but when we open the app directly the notification message is not getting saved.
In short we are not able to know if we had received a notification message if we directly open the app rather than clicking the message from the notification panel.
Is this default behavior ? or is there any work around for this ?
Have looked into many posts on about Push Notifications but haven't seen any threads pointing to this scenario.
This is a normal behavior, and there is no workaround.
If your app is killed by the user, it won't be able to run ANY code before it's manually launched again.
If it's manually launched from a notification, this notification's payload will be handled by your AppDelegate.
On top of that, don't forget that Push notifications are Best Effort. That means that they are not reliable, they can be heavily delayed or never delivered at all. Don't rely on Push notifications to achieve any critical work.
If you need to keep a copy of your notifications in-app, keep them server side and fetch them as you would do with any other object.
In order to execute code when the app is killed by the user you need to implement VOIP using PushKit framework provided by apple.
VOIP push unlike regular push notification enables the app to become active even if the app is killed by user.
a simple question: is it possible to get a message, notification or similar when the internet connection is available when app is killed or not running?
For my purpose, I need a way to synchronize all my notifications because APNs can send only the last message.
EDIT:
I'm wondering how some apps (e.g. whatsapp) are able to sync their notifications when the internet connection is up. If I kill whatsapp, I can receive multiple notification when internet connection is reachable, but the APNS server provides only last message and, for this case, I'm not able to send silent notification. If I should develop a chat application, what are the best practices to work with Apple notifications?
If you send a push notification with a title, text, sound and/or badge property while the app is suspended (was killed / force closed), the device will still receive it, e.g. will show the text as a notification, play a sound and/or change the badge count.
However, your app won't be launched or woken up in the background in this case, so you have no way to handle the notification before the user taps on it. (See this question:
Will iOS launch my app into the background if it was force-quit by the user?)
So if the app was force closed by the user, your only option is to send a notification to be displayed as it is and if the device is offline, only the last notification will be received and displayed by the device.
For more control, you could use silent push notifications to implement "push-to-sync". In this case, the push notification only signals that there is new data to be fetched. The app (if not force closed) loads the data from the server then and triggers local notifications with the right data in the right order. But this won't work, if the app was force closed.
Apple push notifications have a lot of restrictions, so you won't be able to implement a perfect solution. In my opinion, it's fine if the user gets only the last notification when the device gets online after being offline for a while. At least he is informed that there is a new message and after opening the app, he can see the other new messages too. For the "push-to-sync" scenario, I would say that the user has no right to expect that the app works as desired, if he force-quits it.
Push notifications were never intended to be used in the way they are used by a lot of apps by now. E.g. they shouldn't contain sensitive data such as a chat message. They were intended to inform the user that there is new data for the app, so he can launch it to see the new data. E.g. instead of sending the actual chat message text a push notification should just contain the text "You have a new message". Then, you don't have the problem you described. Of course this is a terrible solution in terms of usability.
I cant find a clear answer about this in the Titanium documentation. Is it possible to directly respond to a push notification while the app is killed ?
I know that the callback is called when you open the app trough the push notification. but is there a way to respond when the app is opened manually ?
I tried to use remote-notification as UIBackgroundModes, but this only helps for paused apps.
My goal is to show the push notification in a in-app message center.
You should never rely on push notifications to deliver you payloads, they are too limited for that. If the user receives 5 push notifications and opens the app via the app icon, you will never receive any of the payloads. If he opens the app via one of those notifications you will only receive that payload.
You could use silentpush:
http://docs.appcelerator.com/platform/latest/#!/guide/iOS_Background_Services-section-37539664_iOSBackgroundServices-SilentPush
But the app should always query a back-end to get the actual data. That's how WhatsApp does it as well, as you can see when you open it via a notification it will then still fetch the message(s) form the server.
I basically want to make multiple push notifications in the same application visible in the notification tray in iOS.
This scenario works if my data is on while push notification is triggered via APNS, but only the latest one is received in case I am offline and come back after a while. This functionality is affirmed by APNS documentaion.
However, this is what worked in WhatsApp:
Turned Data Connection OFF
Sent some messages to WhatsApp
Turned Data Connection ON
Saw multiple push notifications received in Apple's Notification Tray
How's this scenario working? Can I use APNS for this? If yes, then how?
See this sample image of multiple Push Notifications in WeChat.
Like you wrote in your question, this is mentioned in the Apple Docs:
If you are sending multiple notifications to the same device or
computer within a short period of time, the push service will send
only the last one.
Link
The only scenario that what you're describing will work is if your whatsApp was open in the background while getting those push notifications. That way whatsApp will handle them as local notifications and will present all of them in the notification center. If whatsApp was closed you'd get only the last notification like any other app.
You can easily test this:
Terminate whatsApp and turn on Airplane mode.
Send your device 5 messages from 1 to 5.
Turn Airplane mode off and lock your device.
You'll only see one msg (the last one you sent aka "5") in your notifications center.
This is how whatsApp is making it work:
While whatsApp is in the background, a single push notification is received (the last one the user sent, "5" in our example). That msg will not be shown to the user.
whatsApp receives it in the method application:didReceiveRemoteNotification:fetchCompletionHandler: and checks against their servers if there are any notifications prior to "5" that the user didn't receive. If that's the case, they will pull that data from their servers and will present it to the user using local notifications which is basically just a way to present data and not related to APNS at all.
It is explained in Troubleshooting Push Notifications. Check for "Some Notifications Received, but Not All" section.
As described you cannot have any control over those push notifications.
However you may know that from iOS7 a new background execution mode (remote-notification) allows the App to be awaken by the system when a push is received, allowing you to process some data, then go back to sleep...
This is probably the trick: using that way to receive the push notifications (silently) and then trigger your own local notification instead as #Segev said. See the UIBackgroundModes here.
I created an app which receives push notifications from my server. At the same time, if some other app is sending push notifications (for e.g., whatsaap, twitter), the notification is getting displayed when I'm using my app. I want to hide all other app's push notifications except my app's push notifications. Can this be done in iOS? I want my app to receive push notifications only from my server but not from the other apps.
Thanks in advance.
Try to think like your customer. Would they like to receive the push notifications of the other apps (whatsapp, twitter, the notification that a very important email just arrived)? Of course they would. Your App is one of many and most probably not the most important one they own.
Let me provide some background first.
Your app can only receive notifications from your service/server.
The user might have apps that are receiving notifications from the respective service/server.
e.g. if the user has FB app, then it would be receiving notification from FB servers.
In the end, you are only responsible for managing your service/server.
There is no way for you to block notifications that are received from other services from your app.
Hope this helps.