Should I continue to use Socket.io? - ios

I am currently in the process of writing an iOS app and it's now been decided that there will no longer be an in-built real time messaging service. This was the main reason around using Socket.io on the server. So basically when the app is loaded it logged in in the background by sending the login credentials with the connection request. Now that I don't need the messaging service, most of the app is just information requests and the server responds with the relevant information. I could still utilize the real time aspect by sending updated information to the device if it gets updated on the server and some in-app notifications could utilize this too. However I'm pretty sure it can be all done using http requests and I'm not sure how likely I would need real time functionality in a future update.
Ignoring time and money, should I fundamentally re-write the way the server and the app communicate or would it be okay to continue using Socket.io and websockets?

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.

How to get updates from the server promptly?

I have an iOS app which displays some information fetched from the server.
The app communicates with the server using REST API, and makes GET requests periodically (or when user pulls-to-refresh). However, we need better synchronization. As soon as data changed on server, we want to reflect it in the mobile app.
How can I get notifications from the server when data changed and update needed? I thought about silent push notifications, but they do not look a right choice here.
Are there alternatives? May socket programming help? I have no an experience in it, but I it is relevant, I will start digging.

iOS Push Notifications: App as Provider?

I understand the basic concept of having a provider talk to Apple's Push Notification Server which then pushes the notification to the phone. Usually, the provider is an app server running on some machine somewhere completely separate from the app.
However, we don't currently have a separate server, and don't yet need one as everything is currently handled in-app. So, is there any way we can use the app itself as the provider to send a notification to Apple's server and thus to another phone?
Basic concept: we have a game and when a user completes 70% of the level, we'd like to notify his competitors that he's close to finishing the game (or that he has finished at 100%).
If it's possible, are there any security concerns with this approach?
P.S. The app already knows who the competitors are because it displays them in a UITableView.
Technically it's possible. If you include the push certificate with your app, and you have a way to send the device token of each device to all other devices that may need to push to that device, you can push a notification directly from one device to another.
However, in practice, that would require opening and closing many connections to the APNS servers frequently (you'll need a connection for each device, and every time a device loses network connection - which may happen often - you'll have to re-open that connection), which will probably cause Apple to block your app from connecting to their APNS server (since they would interpret it a DDoS attack).
Therefore you should use a server.
For future visitors to this question: we wound up ditching Amazon SNS since we spent nearly 8 hours and couldn't get it working the way we wanted. Instead, we setup Parse Push in rough 15 minutes with exactly what we wanted to do, so I would definitely recommend giving it a look.

Chat app synchronization on background in IOS

I have a chat application developed by JS. I want to send PING to server once in a while. Its not a problem if app runs on fore ground. The problem is when user minimizes it or open another app. My app looses its focus and gets into suspended state.
I have following two use-cases.
To keep the chat session open I need to send PING to server (Its an IRC server) every X minutes even the app runs in background.
We also need to check for new messages (by ajax on a local http server) and add a local notification to the notification queue so when user clicks on it app can resume
I have found apple does not allow running apps in the background. if they allow they require special permission. I found some apps does it by requesting finite length execution time.
What is the best way to get highest possible background execution time? As a chat app can I request permission for voip, location or any other way ?
Note: the app will be running in an environment where there is no Internet. Hence push notification will not work here.
Update: After doing a lot searching I found background fetch. It seem background fetch will suite it. But still the problem remains, its not called in a timely manner.
This sounds like an interesting problem. From reading the various comments, it sounds like you want this to work when you're on a local network - so you have wifi, but the wifi router/base station isn't connected to the actual internet?
Because background refresh isn't going to be predictable - you'll never know when it is going to update - you might want to get creative.
You could look into exploiting iOS VOIP support, only without the Voice! Apple has some tips on VOIP here. VOIP basically uses something called SIP (Session Initiation Protocol), which is signalling layer of the call, and a lot like HTTP. It's this SIP layer that you want to take advantage of.
This isn't going to be terribly easy, but it should be achievable. Setup your app to use VOIP, and then look into something like PJSip as your SIP library. Then, on your local network have a SIP Server (I'm sure there are plenty open source implementations) that you can register your iPhone against (so your server knows where your phone is, pretending to be a VOIP phone). This should work, because it doesn't need to go through Apple as far as I am aware... And will run happily on your local network.
Then, the server can send a message via SIP to the handset, as if it were instigating a VOIP session. You app is awoken, gets the messages - ideally from the SIP message if possible - and then just doesn't start the session. SIP was designed just for creating sessions, not just VOIP. When I worked in Telecoms R&D (a long time ago) we were using it to swap between Text/Voice/Video, all using local servers.
You'll have to jump a lot of hoops to make this work, but it would be pretty awesome. I have never tried this actual use case - especially with iOS, but I'm fairly sure it will work. It is a bit of a fudge, but should get you where you need to go.
Good luck!
You can use something like PubNub to build this chat app with iOS using native Objective-C code, or with the Phonegap (Cordova) libs.
The beauty with using a real-time messaging network like PubNub is that when the app goes to the background, you can easily have the chat messages come in on APNS.
When the app is in the foreground, it can just receive them as the native (PubNub) message. And if it needs to "catch-up" with the messages it missed while in the background (but received via APNS), its trivial to implement.
Also, PubNub is platform agnostic -- so you can easily also use it on Web, Android, BB, Windows Phone, etc.
http://www.pubnub.com/blog/build-real-time-chat-10-lines-code/
http://www.pubnub.com/blog/html5-websockets-beautiful-real-time-chat-on-mobile-using-pubnubs-channel-presence/
https://github.com/pubnub/objective-c/tree/master/iOS
https://github.com/pubnub/javascript/tree/master/phonegap
geremy

Create an iOS App that runs as Web Server in background

I want to make an iOS application (for iPad specifically), which behave like a web server.
I saw the examples coming with COCOAHTTPSERVER, but i didn't understand something.
Is it possible for my application, while being in background, to receive a request from another application running in the same device?
If it is possible how can i do this?
Otherwise, if it is impossible, what is the meaning of a web server application, that can't work in background?
My exact problem is as follows: I need an iOS application that can receive a request from a javascript application, running on safari, in the same device. Can i create an application behaving like a web server in background (because safari must be in foreground), or there is another way to implement this?
You can run a web server in the background on iOS but unfortunately only for a limited time (up to 10 minutes max) and the OS can stop it at any time. See this tech note [1] for more info.
If that limitation is acceptable to you, you should use an already existing web server like GCDWebServer which handles background mode for you [2].
[1] https://developer.apple.com/library/ios/technotes/tn2277/_index.html
[2] https://github.com/swisspol/GCDWebServer#gcdwebserver--background-mode-for-ios-apps
This library may make your task much easier.
https://github.com/swisspol/GCDWebServer
No, iOS does not support web servers running in the background.
The reason Apple does this is that a web server has to listen for inbound network requests. Listening for inbound network requests requires that the radios be active all the time. Active radios drain the battery.

Resources