I am trying to develop an iOS app that delivers time critical alerts to staff when certain events occur (handled by a server on the clients site, on the client network). This notification needs to be delivered to the iOS device even when the internet is down (since the alert is time critical it cannot wait for internet to come back up), some client's site do lose internet access often enough for this to be an issue. I don't believe that this is achievable via iOS Push Notification since it requires connection to internet. And the issue with local notification is if the device is asleep for some reason they will not get the alert, unless I have an infinite background operation running. Now battery life on devices is not an issue as they will be rotating multiple devices, so if one dies they can log into another iTouch, and charge the old one. The issue I see is that you cannot have an infinite background task running (to deliver the local notifications) and have it in the app store without some sort of VOIP service also added, and this would be given to our clients so it doesn't really fall under the enterprise license. I have email Apple dev support with this question and have not received any response. Does anyone have any idea the best way to achieve this time sensitive notification (without internet access) with an iOS device?
Related
I have a device, located in a Wi-Fi local network possibly without Internet connection, which sends notifications to the devices that are connected to it using a web-socket.
But when I lock the phone or press the home button, my application goes to background mode and the web-socket connection gets closed, so since then any notification doesn't get to the phone.
I know I can do this by using remote notifications (with Apple Push Notification Service), but my device is intended to work on any Wi-Fi network (with or without Internet access) or generating its own Wi-Fi access point (and therefore without Internet access).
So the question is: Is it possible to have a persistent connection, like in Android where I can maintain a connection in a background service?
No, you can't if you want your app in the App Store.
If not (for example this is an Enterprise app), you can use kind of hacks, like silent audio or voip but this will drain battery a lot.
In iOS, only specific app types are allowed to run in the background:
Apps that play audible content to the user while in the background, such as a music player app
Apps that record audio content while in the background
Apps that keep users informed of their location at all times, such as a navigation app
Apps that support Voice over Internet Protocol (VoIP).
Apps that need to download and process new content regularly
Apps that receive regular updates from external accessories
unlimited backgrounding on ios with silent audio
Apple docs - background execution
I have integrated BlueMix push notifications into my iOS app, and I have verified that the app can receive notifications. However, after some period of time, the app stops receiving them.
When I query the registered device list via REST API at https://mobile.ng.bluemix.net/imfpush/v1/apps/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx/devices the device IDs I expect to be there are now gone from the list. What happened to the devices? Do they become unregistered by some automated process? Is there something I can do from the app side to make sure these devices do not become unregistered?
There are currently some temporary issues with the Cloudant cluster that are manifesting themselves throughout the Bluemix Mobile Services. We're currently working with that team to get a resolution as fast as possible and will update when we know more.
To confirm that this is what is affecting your app: if you retry the request multiple times do you sometimes see some or all of the devices or are you getting an empty list each time?
Also to be clear; there is no intentional mechanic in the IBM Push Notifications service to prune or automatically delete device registrations.
I am trying to implement an iOS chat application using Pusher or PubNub (websockets).
Question: How does message delivery work when the iOS app is in the background?
I understand that Websockets implementations provide real-time messaging and don't cache the messages. Is the message lost because the socket connection is broken when the app is in the background?
If yes, how do I recover the lost messages? One idea is to implement a state refresh protocol every time the app comes to foreground.
PubNub Missed Message Recovery Options
You mentioned PubNub (the company I work for) and as #FrankG mentioned, unless you have permission from Apple to run your app in background (staying connected to internet, and therefore, PubNub), you will not receive any message in realtime.
You can use PubNub's Mobile Push Gateway and receive APNS push messages while you app is in background (but idle/not running) or completely not running (kill state).
When the app is activated again, PubNub can be configured to automatically retrieve missed messages from the channel(s) it was subscribed to, but this is good for short periods of disconnection.
For longer periods being offline, you can enable Storage & Playback and use the historyForChannel API to fetch all the missed messages of all channels you require.
Answer: It doesn't.
If the iOS app is in the background, you are out of luck. There is no official (and Apple sanctioned) way of keeping a connection open when the app is in the background. There are hacks like playing a silent audio track to keep it in the foreground, but Apple doesn't approve of such hacks. You'll need to use APNS to send an offline message to bring the app to the foreground so it can reconnect.
And you are 100% correct that the WS standard does not address caching. That has to be performed by another subsystem in your architecture.
The Kaazing Gateway (disclosure: the company I work for) has a feature in our messaging Gateway that caches the last value sent. When the client reconnects (our client libs auto-reconnect), they will see that value.
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
My company offers an iPhone app for day traders which basically tells them when it's a good time to buy or sell. A cluster of servers generate these BUY and SELL signals and need to be delivered to a customer's iOS device in a minute or less. For all other mobile clients we've developed, we are allowed to poll the server in the background (once per minute), to check for updates.
In iOS, however, it seems that doing anything in applicationDidEnterBackground that has to do with times or polling isn't an option.
This led me to look at push notifications, but from what I am reading, they aren't reliable. They employ a send-and-forget methodology, which there's no guarantee they will be received.
You can see the problem with this. If we issue a BUY signal and the user acts on it, then a SELL signal is generated 10 minutes later and send via push, but never arrives, they could lose a lot of money.
So, is there a good way to do this or am I out of luck? Thanks!
There are two intermediaries between your server and the user's device: a) Apple and b) the network.
Apple does not guarantee the delivery of all notifications; only the most recent is guaranteed to arrive and only for a limited period of time. For more information, check out the "Quality of Service" section in Apple Push Notification Service.
If the device is accessing the network through a mobile carrier, things may get ugly. I have experienced situations where, some notifications didn't arrive until much later, and some got lost entirely. From my experience, carriers protect -with zeal- the quality of their own services, rather than those of third parties like Apple. An SMS/MMS will not normally be lost, while a push notification might.
Polling the server would be a viable alternative for your app. Alas, Apple doesn't allow networking operations to take place for apps that have been put in the background state (except for Newsstand downloads and VoIP).
Some apps seem to do push notifications really well (GroupMe) while others don't. If you're really worried, you could use a service like Twilio to send the user an SMS message with a link that would open your app and give it some information. So the SMS could say "SELL SELL SELL yourapp://stock=APL" or something like that. This obviously won't work for iPod touch users or iPad users (although I don't know if that will be a problem for you.
Try using Apple's own push notification service: http://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html
It's quite easy to implement, with just a few lines of code in the application and a bit of PHP and JSON on the server to do the sending. The good thing is that your server sends the request to Apple, and Apple's own servers handle the delivery to the device securely and reliably. Notifications are usually delivered within 10 seconds of being sent (unless the device is offline, then it will be delivered when the device comes online).
From my experience with push notifications, I haven't lost a single one, and there is a delivery option that continuously attempts to deliver it until it is successful, and there is even a server side callback API of some sort available that lets you check the status of your notifications. You could also try a service like Urban Airship to do the work for you.
You could also try using one of Apple's background modes as part of this (such as receive the 'BUY' as a notification and have the app wait for the 'SELL' in the background. The biggest limitation is that the app can only run in the background for about 10 minutes at a time, so you would have to use a workaround like playing music in the background (or making stock announcements like a music track ;P), or prompting the user to reopen the app to continue the background session.