APNS? Or Polling? Which is more reliable? - ios

I'm working on a small messaging app, similar to IM or SMS text messages. I'm obviously planning on using Apple's Push Notification Service (APNS) for notifying users of new messages when the app is not running. The question is, what about when it is running? Should I rely on APNS to notify the app when to refresh the list of messages that the user has received? Or, should I do periodic polling to grab any new messages?
My app will be making use of RestKit 0.20 as its web service client library. Polling should be easy enough to configure there, but I'm concerned about the additional overhead of creating the connections, as well as the increased bandwidth utilization that polling will create.
Is APNS reliable enough that I can use it to trigger a UI refresh when a new message is received? Or should I handle it manually within the app itself via polling?

APNS is very reliable, so you can get away with using it to refresh the application when new messages come in. However, it isn't 100%, so I'd plan on keeping a Refresh button close by to allow the user to poll as they wish.

Related

Is there a way for the server to push data to an app without using push notifications?

I'm looking for a way to push data to an app similar to APNs but that doesn't use APNs. Is there a way to do this? The reason I want to do this is if the User disables notifications I want to still be able to send data to the app without needing user input such as a pull to refresh or what have you. I only want it to happen when the App is in the foreground.
Basically, I want it to use push notifications like normal, so if there is new data available the user is notified if the app is closed so the user can click on it and have the app open and display the new info. Then if the user disables push notifications through the settings the user will no longer receive notifications, but the app will still refresh if there is new data available.
I tried using GCM/FCM but that just piggybacks off of APNs so it won't work if the setting is turned off for notifications.
Is this even possible?
If the app is in the foreground, you have two options:
1) Poll - For example, every few seconds to you make a network call to poll for new data. This may be possible if you can guess a frequency at which you get new data. But as you can imagine, this is pretty impractical/wasteful if you have to do this very often.
2) Push - You can open a persistent HTTP connection (web socket) and push new data to the client from server. This is more difficult architecture (publish-subscribe) to implement than polling, but definitely worth the time if you implementing any sort of real time system (think new Facebook posts on the timeline, new tweets). For websockets, you can use a home grown solution (eg http://socket.io/) or you can use many available 3rd party solutions (like http://pubnub.com etc.)

simple messaging app without server

I am new to iOS development and started a tutorial on a simple messaging app using Parse as the server. The way they have it coded, the app queries parse every time a message is sent(to save the message) but seeing as Parse only allows 30 req/sec under its FREE plan how would one go about making a messaging app? Is it standard convention to save data to the server for each message? It just doesnt seem practical to have a substantial user base on an app that can only query the serve 30 times a second.
The question simplified is: what is the standard convention for the relationship with servers for a simple messaging apps? Does the app save each message to a server or is there a work around using push notifications? (But even with push notifications the app would have to be opened to receive them, at least thats from my limited understanding of pushes)
It is not practical to have a substantial user base for a messaging app with only 30 queries per second. Parse is running a business. They give you 30 API req/sec so that you can try out their service and see how it works. But if you are designing an app for a significant user base, you will surely have to pay, as you are expecting Parse to run the servers for you.
With that out of the way, it would be normal for a (typical) messaging app to make at least one API request per sent message to the server. The server is responsible for accepting, routing, holding, and delivering messages. It would also be normal for that sent message to result in a push notification, and an API request from the client app to retrieve the message. The general workflow would be:
User sends message
App uploads message to server
Server determines where message is headed
Server sends push notification to recipient
Recipient app queries server for pending message(s)
Recipient app displays message(s) for recipient user
That's two API requests and a push notification for each sent message.
Beyond that, depending on your messaging service design, the server may also store all messages so that later, on a different device, a user can open the app and it will download the history, so as to appear synchronized.
Now, surely there are ways to reduce the number of server API requests. Your app could batch messages locally, your server could batch push notifications, and your clients could batch queries (or you could do all three). All of these options could help dramatically reduce the number of server API requests you pay for, but they will also reduce the responsiveness and user experience of your messaging service.
You could also design a sophisticated peer-to-peer communication system (like Skype was in the past) removing servers from the messaging flow. However, you would have to design complicated authentication and verification systems, complicated routing systems, complicated storage systems, etc. A lot of work. And even if you did, I don't know if Apple would allow it on the App Store. A lot of time, work, and uncertainty to avoid paying the small cost for a server.
Regarding push notifications: Push notifications are sent from a server to a recipient client app. Your iPhone cannot push notification another iPhone. There will always be a server in the middle. Your app does not need to be open to receive a push notification. iOS will receive it, and then deliver it to your app. If your app is closed, iOS will (partly) open it in the background to deliver the message.

Is it possible to use server-side events to notify an iOS user despite my app not running, without using Apple Push Notification Service?

I am considering using EventSource (server-sent events) to send notifications to my iOS App users, instead of APNS. This is great when app is active, but is it possible to ensure these users receive my messages when my app is not currently running on their device? Or is the only way to do this APNS?
If you need your events to arrive in real-time (like a messaging system), then APNS is probably your best bet. APNS is the only way to send realtime messages from a server to your app. However, it is wise to know that there are downsides to push notifications.
If you don't care about real-time events (not a messaging system), or if it's okay if you get the events a bit delayed, you can use background fetching to periodically poll your server for new events.
Objc.io has a great article discussing some of these: http://www.objc.io/issue-5/multitasking.html

Notify iOS app to update its content

How can an iOS app be notified that it needs to update its content?
I would like to have an app that listens for update alerts that trigger a download rather than doing a data request to be able to stay in sync with the server.
What is the correct way to have an iOS app that needs to be in sync with a server stay in sync while minimizing network activity?
Im aware of using a cache locally, NSURL Cache or Core data etc. and adhere to the timeout in the http header etc. but I would like to correctly setup a sync mechanism without having an update button that a user needs to press to get updates.
I have thought of implementing a dispatch_source on a socket but wont that keep the network active and drain battery?
Rather than request a token for the version of the data to sync from the server I would rather like the server to notify the device that it needs to update. Is this practical?
How does the OS handle listening to push notifications? Is it on POSIX level?
You really have two options here:
Client Side Polling: call the server and ask every so often. For 99% of apps this is fine as it's not that big a deal for someone to run the old version during the interval between polling.
Real-time Server Push: If for some reason you need to disable the old version as soon as you push a new version, you could do a server side push. You would not want to use APNS for this (user may deny APNS, delivery not guaranteed, etc). You would want to use a cheap push service like PubNub or Pusher for this to guarantee real-time delivery. Or code you own version using the same principles of these services, but really why re-invent the wheel?
There are two common, as far as I am aware, approaches to doing this on iOS;
Regular GetUpdates calls to the server at an interval (Fairly standard across any platform I think)
Apple's Push Notification Server(APNS) if anything changes on the server you can push a notification to the device.
At work we typically implement both options because there are a few issues with APNS;
They are not guaranteed to reach the device, if the device is offline the APNS service will store the Notification for a limited time in the APNS system upon which it is forwarded (if it hasn't expired)
If multiple Notifications are sent while the device is offline only the most recent notification is sent
If the device is offline for a long enough period of time all stored notifications will be discarded
the user has to allow Push Notifications to be sent to their device because it suppliers and identifier that you can use to determine the device

If I use Apple Push Notification service for instant messaging will apple block my account?

I want to create an iOS chatting app using APNS. If I have 10,000 active and they are continuing chatting, will apple block my developer account ? Is there any limitation regarding this?
I would discourage you from using APNS as a backbone of an "chatting app".
If you need fast chatting functionality you should write your own TCP-socket based server.
If every-few-second syncing is o.k. you can get away with a HTTP-based server backend (but all the pull-syncing can be hard on network traffic - so TCP-socket is still better choice).
You could however use APNS for fallback - when your app on certain device is not responding (i.e. is not connected to server) you can send an initial message trough APNS (to wake up your app & to notify the user there is a message waiting for him).
As soon as the user opens your app you should switch back to your TCP-socket or HTTP request based server communication.
As for your question: no, Apple would most probably (one can never know for sure) not reject your app just because of using APNS for chatting. But note (as the others said allready): messages between two users will get "lost" if they would interact too frequently - see the link Roman Barzyczak gave you.
"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."
more information: http://developer.apple.com/library/ios/#technotes/tn2265/_index.html
but Apple wont block your developer account :)
You can use them for messaging but you are going to quickly find out that there is no guarantee they will arrive. This is known as the black hole of push notifications. ;-)
I like this answer here.
First try to use an APNS only solution.
Make your push notifications stateless (they only serve as "Hey you have some new stuff in the server").
So when the client gets a push notification it asks the server for new data (messages or other stuff).
Use OneSignal to simplify the code that sends push notifications (from the back-end). If a user in your app gets a message after 10 seconds he dose not care if you used TCP,socket.io or xmpp...
Even Whatsapp's messages can take couple of seconds to arrive.
A chat app is not a realtime game. A delay of couple of seconds will be acceptable by end users.

Resources