This is more of an is-it-possible question.
I am building a pubsub application for the iphone using XMPPFramework and Openfire.
When the user has the pubsub app in the background, the app sends "keep alive" packets every 10 minutes or so to keep a persistent connection. Any messages delivered will show up as local notifications.
But what about if the user has killed the app or it's been a week since they've used it and the app isn't in the background? How would they know that they have a message waiting for them?
Is it possible to combine Openfire's pubsub service with Apple's push notifications? Am I on the right track? Thanks!
The limitations you're envisioning were constructed purposely to only allow certain types of applications to run in the background with long-lived connections indefinitely (namely, VOIP applications). You could experiment with setting the UIBackgroundModes key to 'voip' (see: Apple's Documentation).
Non-VOIP applications don't have this luxury (presumably as a safeguard against battery life or network utilization issues) and won't be permitted in the appstore if they have the VOIP UIBackgroundModes value set.
Consideration of Apple's Push Notification Service is definitely the right approach, IMHO.
Related
Maybe someone ever solve the problem with stable connection to server when application is in background? I need to transfer audio data from server to client app.
I know about all hacks for iOS how to keep alive application, but I need legal methods to solve this problem. Maybe you have any idea?
I found that I can send VoIP push to device that will wakeup my app and then establish tcp connect to my server but this socket will be keep alive about 30 seconds (as I see in log, every 3 seconds fires timer in iOS app that send data to server) this is not enough for me.
Maybe this project https://github.com/SmallSharpToolsOpenSource/Speakerbox will be helpful for someone.
And this video https://www.youtube.com/watch?v=lXJ1LDjL4Os
And official answer from Apple tech support:
PushKit is how voip apps can
reliable receive silent notifications, while CallKit is basically a UI
framework voip apps can use to notify the user about calls. Note that there
is NOT any direct connection within the APIs- for example, a voip app can
generate a local notification (instead of using CallKit) or simply do nothing
and “ignore” the notification entirely. Similarly, a voip app could “fake” a
call at anytime by simply telling CallKit that there was an incoming call (our
sample code for CallKit did exactly this).
Anything your app could previously have done when
it received voip socket traffic, it could also do when it received a PushKit
notification.
Standard voip apps
actually operate in two COMPETELY unrelated “modes”:
1) While waiting for an incoming call, the app is suspended until “something”
(PushKit OR a voip socket) wakes the app to tell it about the call.
2) Once a call has started, the app has an active audio session and is relying
an the standard “background audio” behavior of iOS, just like a wide variety
of other audio apps (for example, any streaming music app).
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.
I want to sync my local DB with server when Push notification came, but I am not able to do it with Silent Notification because application:didReceiveRemoteNotification:fetchCompletionHandler not called when app killed by user. So, I did not know how to do it, then I read about push kit but don't know is it possible to use push kit without VoiP feature. Please tell me is it possible or not??
If not, suggest me any other idea , how will I run background task when app killed by user??
In my experience as well as others on SO - you get rejected for trying to leverage VOIP as a workaround. See below for actual response from apple dealing with a similar attempt.
2.16: Multitasking apps may only use background services for their intended purposes: VoIP, audio playback, location, task completion, local notifications, etc.
2.16 We found that your app uses a background mode but does not include functionality that requires that mode to run persistently. This behavior is not in compliance with the App Store Review Guidelines.
We noticed your app declares support for VoIP in the UIBackgroundModes key in your Info.plist but does not provide any Voice over IP services.
We recognize that VoIP can provide "keep alive" functionality that many app features would like to use. However, using VoIP in this manner is not the intended purpose of VoIP, which, as indicated in the iOS Application Programming Guide, is that: "A Voice over Internet Protocol (VoIP) application allows the user to make phone calls using an Internet connection instead of the device's cellular service."
Seems that the only way to restart the app when it was killed by user is to use PushKit.
It is possible to use PK framework in your app without Voip functionality, but I can't guarantee you, that your app will not be banned while posting to AppStore.
I'm currently struggle with annoying store-and-forward function limitation of APNS. Here is a quote from the Apple docs:
If APNs attempts to deliver a notification but the device is offline,
the notification is stored for a limited period of time,
and delivered to the device when it becomes available. Only ONE recent
notification for a particular application is stored. If multiple notifications
are sent while the device is offline, each new notification causes the prior
notification to be DISCARDED.
I specifically make ALL CAPS for the keywords of my problem. In Google Cloud Messaging notifications service their store and forward function have much more capabilities:There is a limit on how many messages can be stored without collapsing. That limit is currently 100. If the limit is reached, all stored messages are discarded. - so Google service can store up to 100 push messages for a max time of 28 days. And in addition to this they have also coalescing (collapsible) notifications but for 4 different collapsible messages. And in APNS all we have is - one recent
notification for a particular application is stored - it is quite a limited behaviour for my app (I need to store at least four different push notifications while the device is offline at one given moment of time).
So I'm interested are there some ways I can improve store and forward capability of APNS?? Can I in some way make APNS to store more push notifications for a specific device?Or at least store several coalescing notifications as in Google collapsible messages? Some third party solutions or whatever? May be I missed something in APNS docs? I know we can orchestrate apple push notification on google platform - but I think it is not a solution because of its unjustified complexity.
As you found yourself in Apple's APNS docs, there is no way to store more than one notification per application for a single device. If you want to compare it to GCM, APNS server acts as if all notifications have the same collapse key.
No third party solutions can work around that, since Apple doesn't return an acknowledgment of delivery to the sender of the notification, so the server (whether it's implemented by you or by some third party provider) has no way of knowing which messages to store and resend (assuming that all the messages are valid and were not rejected by APNS server).
Apple Push Notifications are not intended to deliver important data. Their purpose is to notify the user of the app that new data is available at the server, which allows the app to load that data if the user chooses to open the app. That's the reason why they don't store more than one message per app for the same 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.