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.
Server: Pusher gem(rails) Client: Pusher Swift
How do I detect if the client is gone offline(app in background) or come back online(app in foreground) using Pusher gem?
What I want to achieve is sending APN to the client, when the client enters background without querying client online flag(s).
Is it possible to achieve this? Is there way to check the status of Event trigger if the message was received by client or not?
Thanks
There are a few ways you can achieve what you're trying to do.
If you're using a single channel per client you can use the channel_existence webhooks as described here. As each channel is limited to a single user, you will receive a channel_vacated webhook whenever your client goes offline and a channel_occupied webhook whenever your client comes online.
If you're not using a single channel per client, you could usepresence channels and webhooks. You can configure a member_added/member_removed webhook every time a user joins/leaves a channel. There is an additional message overhead associated with this, as each user in the channel will also receive a member_added/member_removed webhook over the websocket connection.
I'm trying to make it a notification. What I have in mind right now is a notification system similar to that of Skype.if any person can be a create a new event in application that time show notification in the header.
Any help/advice/answer would be greatly appreciated.
You are going to need a model for your notifications and subscribe all your users to a websocket connection. When they visit the site any type of notification gets broadcasted to all users that are connected to the websocket at that moment. If you like, you can send also an email after the notification was created.
Depending on the version of Rails you are using you will have to use either Faye websockets (https://faye.jcoglan.com/) for 4.X or use ActionCable (websocket) in Rails 5 (http://edgeguides.rubyonrails.org/action_cable_overview.html).
Read as much as you can about how to use websockets and how the connection works. It can be a bit tricky to understand.
If you are willing to use a service, you can use Pusher. They have a free tier and then it starts at around $49 a month depending on the number of connections and amount of messages (notifications) you want to broadcast. (https://pusher.com/)
I am working on an application which GET and POST information to a server. I am doing so using AFNetworking framework. My aim is to push a notification to a client whenever someone posts new info to the server. Eg: a new grade is published, the student who's grade was published must receive a notification on his iDevice.
Although I am not familiar with how Apple Push Notification works, from what I read I concluded that I need to add server side code in order to trigger a notification.
Note that I don't have access to the server. Service is provided by Fedena.
Any suggestions or hints from where to start?
APNS needs a server in order to work. The usual flow goes like this:
The iOS Application asks user to enable push notifications
Upon access granted, a device token is generated and then must be sent to the server.
Your server must be setup with the proper APNS certificates generated from the Apple Developer site
Then in your server's, when a new post is created, you need to add some logic where you load all the APNS token you've received already and then send the notification to the devices.
This is a very simple flow description but I guess you understood that you need to have access to the server to be able to do what you are trying to achieve.
Some third parties exists to handle push notifications (like Urban Airship), but those push notifications are usually pushed manually from a person, and not triggered from a server event
I recommend that you can use secondary server of your own as intermediate and use it as infrastructure back bone.You can use SignalR library. Use secondary server as to create connection between two devises. One client will push events and another client will listen to events.
Here is the link to the signalR library code written in IOS.
I am currently using these library. What you can do is start hub and connection using these library.
This library allows invoking method on server. Something like this.
[_hub invoke:#"MehtodName" withArgs:params];
What i would do is to create event registry on server. So one client can listen to event on server and other can push events or vice versa.
So your student device can invoke method "subscribe to events" and server will add it into the registry list. You can create secondary service "Publish Events". Grade publisher can publish via calling this method. Here publish events will look up registry and find interested clients and call desired method on client.
Read more about signalr through this site.
Benefit of using Signalr Over APNS.
Cost Effective. As this will save you money which you might have to pay to Apple for pushing notification.
Can Easily make it cross plateform in future. Just have to impletement similar library in Android/Windows.
Quicker as the data does not travel to apple server from your server.
Worst case you can fallback to apns any day, just put push notification code in any of your secondary server methods.
I have done battery and performance testing as well and works perfectly fine.
If you wanna know, here how it handles connection which is very reliable.
SRAutoTransport chooses the best supported transport for both client
and server. This achieved by falling back to less performant
transports. The default transport fallback is:
SRWebSocketTransport
SRServerSentEventsTransport
SRLongPollingTransport
Let me know if you have anyother question. i am currently doing similar work, might be able to help you with your issue.
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.