Is there a technical reason why we shouldn't include message body in APN notifications? - ios

We're creating an IM app for iOS devices, and we're using APN notifications to inform the user each time one of their chats has a new message. Reading the documentation, Apple advises, "Because the delivery of remote notifications is not guaranteed, never include [...] data that can be retrieved by other means in your payload."
This seem like a bit of a non sequitur to me. Just because the data can be retrieved by other means, is this a reason not to put it in the notification payload? If we include chat message bodies in our notification payload (where the size of the body is going to be no larger than, say, 1KB), we can cache the message and display it as soon as the user opens the app, instead of the app having to send off to the server for the message, introducing an extra delay.
Sure, APS notifications may come out of order, and delivery isn't guaranteed, so we'd use message dates to order the messages and call the server to get any messages that weren't delivered through APS. But for the messages that did get through via APS, I can't see why we wouldn't just include the entire message body in the notification.
Apple's documentation gives the example of an email, where the email body would not be delivered in the APN body but downloaded separately by the app. However, emails are much larger than IM bodies, typically, and can be multiple megabytes in size. Our IM bodies would be much smaller, so that isn't a good example.
Am I missing something in that there is a technical reason not to include such smallish IM message bodies? It kind of makes me wonder why notifications can be up to 4KB in size if you're not supposed to bundle this kind of stuff.

The link you provided, is from Documentation Archive, when opening it, I see a disclaimer
This document may not represent best practices for current development. Links to downloads and other resources may no longer be valid. For the latest information, see User Notifications framework."
In User Notifications framework guide, there is this Generating a Remote Notification page, which instead only points out that remote notification should not contain sensitive data, or, in case it's really necessary, sensitive data has to be encrypted.

Related

Websockets vs. iOS Push Notifications

Take an iOS app like Instagram. Instagram is fundementally a real-time application that updates its UI whenever a user interacts with you. For example, if someone likes your post and you are using the app, the UI is updated to trigger dopamine release and inform you that something has hapened to one of your posts. Similarly, when someone sends you a direct message on instagram, while using the app, you see the message spring down from the top, all in real-time.
In terms of implementing such real time features it is obvious that a naive HTTPS polling approach is far too inefficient. Thus this leaves two strategies:
1.) APNS Push Notifications:
When a user likes a post, sends a direct message, comments (etc.), send an HTTP POST to a backend server that will then update the database and send a silent Apple push-notification to the device of the recipient. The recipient, which is using the app, will receive the pushed payload and will send an HTTP GET to the backend server to fetch the needed data (ie. the contents of the direct message sent). The UI is updated in quasi "real-time".
2.) Websockets:
Whenever any user opens the iOS app, connect the user to the server via a websocket. This means, that all users currently using the app are connected to the server via their own websocket. When a user likes a post, sends a direct message, comments (etc.), the app sends a message to the server through the socket indicating the action. The server, before updating the database, finds the socket associated with the recipient and forwards the message through the socket to the recipient. Upon reception of the message, the UI is updated in real-time
Which of these approaches is scalable and better suited for a production environment?
TL;DR You'll love websockets + Combine framework, event driven to update your UI smoothly. APNS can be somewhat unreliable in terms of deliverability and resource/database costs, and to me is more of an information center.
Reasons to like websockets:
Decreases DB costs (e.g. finding device to send to)
You know when the user is not using the app, decreasing outbound data costs
Latency and faster practically speaking (more in depth in the websocket paragraph)
To answer the question: websockets are scalable based on your user count obviously. APNS is not server side testable in the CI, not cross platform, and not exactly feasible in terms of resource consumption.
I have a bias with websockets. But to present why I like it more, think about the efficiency given by your Instagram example.
To me, websockets == Event Driven, APNS is a simple information center.
APNS:
You sign up with APNS and you save the device in your backend. Great, every time an action is performed, like someone liking your post, query your backend, find the device that is linked to the OP, then send it outbound (which costs money if you think cloud computing costs). And you have to do that every single time someone likes your post (obviously you can aggregate, but why bother when you have websockets?). So database costs is one thing to think about. Additionally, a user could be muting their notifications. I don't have Instagram, but something efficiency wise they could have done (if not by sockets) is updating their UI based on incoming notifications for likes/hearts rather than a websocket connection. That's slow in terms of latency, costly, and unreliable if marked as spam. However, APNS has the benefit of not needing authorization unlike websockets, but...
Websockets:
When we approach websockets, you only authorize once (at least for mobile applications). You're removing outbound data costs (in terms of $$ and latency) by removing stuff like headers. You want to send small chunks of data, and sockets are just sending text/binary (I like to create commands out of them using JSON. A notable example is GitHub). When your user is done with the app, you close the connection and you don't need to send anymore data via APNS. Your server itself can be communicating with a single websocket via something like Redis PubSub in order to update your UI when someone uses a POST request to heart a post without needing to send some push notification. That's a win for the liker (who doesn't need to wait for that push notification to be sent) or the other way if you offload it to a background task (the OP doesn't need to wait). Websockets == Event Driven:
Small data chunks that are constantly delivered (as in a lot) is much better than having APNS in which it can be slow to actually deliver, especially if you're flooding Apple/your user with notifications, marking you as spam. Although, disclaimer, that's just my personal belief and speculation depending on your use case.
You're removing those unnecessary database costs.
A downside would be keeping the connection alive.
Personally, I've used websockets with the combine framework recently for a chat application, but it can be used in so many different circumstances. Updating a Facebook feed/comment section, live notifications via the websocket instead of APNS, even posting content.
APNS is not guaranteed to be delivered, especially if you have a lot of notifications - I don't remember where I read that, but after some threshold per min it'll stop working. Also, you'll have to send them to all your users, not just online ones. It's possible to send silent notifications, but it's still not optimal.
That's why websocket is a preferred way. Also you can use something like https://github.com/centrifugal/centrifugo, which is a helper for your server, that'll hold all the connections, and is very stable.
It is not one out of two, even the web-socket isn't failsafe, but all of above should be considered for an effective communication, when the app is in foreground use a web-socket to listen for any updates from the server, expect a confirmation from client when something is delivered by socket, if the web-socket connection is not active or the there is no confirmation response deliver the update through APNS/FCM, as APNS/FCM it is not guaranteed to deliver, deliver the updates when next Socket connection is successful.

Swift Clear specific remote notifications

We are currently developing an IOS application. The app should basically inform the staff member about new events/requests and the staff member has the option to cancel or accept the event (e.g. customer asks: "I d like to have a coffee", the staff member says: "okay, I'll do it" or "sorry, can't do it"). The idea is that the request appears on multiple smartphones (from multiple staff members) at the same time and that the notification has the buttons for accept/reject included.
The thing is we would like to solve this using Notifications (remote). But there is one thing which is not clear to us. Lets says I receive three requests/notifications. But until I have time to check them, on of the other staff members already resolved one of those requests. Is it possible, that this given requests can be cleared/removed from all staff members phones? Because otherwise I am handling a request that has already been resolved?
And what would be the best option to solve it.
Push remote notifications for every request
Push silent notification for every request and then clear out all notifications on the client, get the new/current requests using REST (GET) and add a local notification for every request?
Thanks a lot for your help.
Regards
I think second option is good.
you can refresh the data using REST api after receiving silent push.
I'm thinking best option is use Push silent notification because end user (Application Holder) will not get clue of that and it is best for us.
I would recommend 1st option
Send remote notification for every request
Handle duplicate request from backend
I think 2nd option is not reliable
APNs treats silent notifications as low priority and may throttle their delivery altogether if the total number becomes excessive. The actual limits are dynamic and can change based on conditions, but try not to send more than a few notifications per hour - source
And Individual notification can't be removed - Check this:

iOS - Push notifications and background threading

I have a service that allows user to enter the type of events they like, and whenever a new event that fits those criteria is available in my database, I want them to get a notification.
I have been looking around at the best way to handle it and I have found two possible solutions, but I'm not very clear with which one I should use and how.
First, a solution that looked great was the didReceiveRemoteNotification method and the usage of remote silent notifications to tell the app that new content was available. But my questions remains: how can I send this remote notification to the user if I don't know which criteria he has. I mean, how can I send this notification using PHP? I'm a bit lost here.
So I found another possible solution that does look a lot like a hack (iPhone - Backgrounding to poll for events), to be able to make your app execute a method every XX minutes while it is in background. This would be way more battery consuming and I'm not even sure it would be accepted by Apple, but at least it is clear as to how it works: the app downloads data from a link with the parameters that fit the special criteria, and if there is new data, it sends a notification.
How could I combine both these methods?
EDIT
I think the main issue on my side is that I don't understand how I could check a certain PHP file whenever new data is added into mysql and make sure that it fits the criteria of the user and then send the notification. That is the part that I don't understand in the backend PHP usage.
Your flow should be like this -
Mobile -> BackendServer(PHP) -> APNS server -> Notifications->Back on device.
User will submit her/his criteria to server then server will process on that and send request to APNS server.
The APNS server will send remote notification on her/his device based on criteria requested.

can content-available be used in a non-silent push?

We'd like to send a "regular" push (with an alert in aps) but with a content-available as well.
This way while the user reads the message, we already do some processing and when he taps, the app is ready.
The documentation at
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html
is a bit confusing in that regard. Would it work? I've only used them separately in the past (either only alert/sound/badge or content-available).
In case any one who finds this is wondering, i have tested, and with ios 9.1-10.2: in order to do background processing, alert/sound/badge is insufficient and you must add content-available.

Iphone - Notify from the server to the client when an event occurs

im stuck in a situation
SITUATION : I have a situation wherein i answer some questions and get points according to the answered questions. if my points become say 10 i win some gift using a QRCode. (there is a qr code that is generated to the user, and when the qrcode is scanned from someother device which has a scanner app or any other scanner, it gives a link to that online store. This link can be opened from any browser.) The gift is accessed from some online store by scanning the QRCode which gives a link to that online store with some unique id and when the gift is accessed/taken the server is notified that the gift is accessed/taken from that online gift store and the QRCode status is updated to invalid on the server database. Now once the server gets the notification that the gift is being accessed/taken, the server should immediately notify my iphone app that the gift is received so that i can immediately show another congratulations image or something.
POSSIBLE SOLUTION : i thought of one possible solution wherein i check upon the qrcode access status change on the server every say 60 secs and display the image accordingly. I dont know how efficient/correct this way would be though.
ISSUE : but before i refuge to the above solution, i want to know, can this notification happen from the server without my app trying to call or fetch the update from the server? I mean, my app comes into the picture only after the server sends a notification in the form of a msg or some xml or something..
Any help would be deeply appreciated.
You can open a connection to your server using CFReadStream, add the stream to your runloop and set up a callback function. Whenever the server writes data to the open connection, your callback will fire and you can then read from the stream to get the data the server sent
More info here: https://developer.apple.com/library/mac/#documentation/Networking/Conceptual/CFNetwork/CFStreamTasks/CFStreamTasks.html
You could try to check Push Notifications. But it's impossible to determine on server side if notification was received on client side or not (if you won't implement it by yourself, but you'll probably wont cover all the possible situations, like when your app is not launched and notification came).
you can try to use XMPP protocol, which is most commonly used for chats/mails, where the changes in the server is notified to the clients.
Apple Push Notification Service is meant to solve these types of situations.
Hope it helps:
Apple Docs: http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW9
There is a nice tutorial: http://www.raywenderlich.com/3443/apple-push-notification-services-tutorial-part-12
Video tutorial: http://www.youtube.com/watch?v=cKV5csbueHA&feature=relmfu

Resources