I'm trying to place OpenTok video calls within an iOS app but am stuck on a good mechanism for notifying users of an incoming call in real time (within a few seconds). Are push notifications my only feasible option or is there some other way? Would like to avoid this since APNS makes no guarantee of notification delivery.
I suppose I could create some server scripts that poll every few seconds, but it seems like there must be a better solution.
As a VoIP app, this app is allowed to register a socket that the OS will monitor for you, and wake you when there is traffic on it. Your app will connect to your server and perform a long-poll. When there is a call, your server will send data to the client on the connection, and if your app is suspended, iOS will awaken it to deal with the incoming data.
VoIP apps are allowed to set a keep-alive timeout, so that you can periodically reconnect to your server, and are automatically launched on boot to service incoming calls.
See "Implementing a VoIP App" and "Tips for Developing a VoIP App" in the iOS App Programming Guide.
Related
I'm developing an app for our security company, that needs to receive alarm events in a matter of seconds. So this is the main event flow:
An alarm goes on in one of the buildings
Our server gets that alarm info immediately
Server distributes the alarm message straight to the app of
responsible person
app starts beeping, until the responsible person doesn't interact
with the app and sends a "message received" status back to the server
location tracking of the person is triggered, and data being sent to the server.
I tried using APNs, but the delivery time there $uck$. Since this data should be delivered ASAP, I'm wondering if someone has any clue, how to deliver some data to the iPhone in realtime?
I see PushKit is available, but only for VoIP applications, which this isn't. And the app wont pass the approval in the AppStore if I use that.
Any pointer will be welcome!
Thanks!
Please note that all Push Notification services must go through APNS, and APNS is the fastest method since it is socket-based, for any other way without push notifications, you need to setup a socket listener on your server and handle the socket on the client using SocketIO for example, this is the fastest method for real time interactions.
And you can use a cron job to fetch data by API each X seconds for example, but it is not fast or real-time as socket-based platform.
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 have an iOS app that plays music with the MusicKit API. I want to write a companion app for macOS that communicates with the iOS app.
For example, my iPhone is playing music. When a new track starts playing, a notification appears in the macOS app. I can click a button on macOS to skip to the next track on my phone.
What's the best way to communicate between devices like this?
I think there are two important use cases:
For static data like account details and preferences.
For real-time messages.
I could do everything via a remote server but I wonder if there's a better way.
The user needs to have your app installed on iOS and macOS and needs to separately grant permission to receive push notifications.
Keep in mind that Apple does not guarantee the real-time delivery or delivery at all of remote push notifications. Remote push notifications may also be discarded by the APNS if many are sent within a short timeframe. It is not recommended to use the APNS for user-initiated actions such as music track controlling, as the user expects an (immediate) result. A web socket or other permanent connection between your server and its clients should be used instead.
Playing music on one device, stopping on another:
Request permission to send remote push notifications to get the unique APNS token for each device.
Store the device tokens on your server.
Make the iOS client notify the server that the user started playing music.
Make the server send a remote push notification to the macOS client via the APNS.
On the macOS client handle the user interaction with the push notification and report the user action back to the server.
Make the server notify the iOS of the user interaction via a web socket connection, rather than a remote push notification to ensure that the client handles the user action.
Make the iOS client skip the track.
Synching user preferences:
Store preferences on server for every change.
Request preferences from server on every app launch or dynamically when the preferences change by triggering the request through a remote push notification by the server or via a web socket connection, depending on how real-time the synchronization should be.
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.
Is there any other way for the server to send data to it's client? Of course that the client could poll the server each 3 seconds to check for updates, but this is not scalable.
If your app is in the foreground then the options are:
- the server sends an Apple Push Notification to the device, as your app is in the foreground the OS will deliver the APN to your app uses it as a indication that the server has new data for the client.
- you poll
- you use a technique like, or a varient, of Comet.(basically keep a connection active which the server pings when it has data)
If your app has moved to the background and you are not suspended (you have registered a task via beginBackgroundTaskWithExpirationHandler: or you are a valid background app) the options are the same except the APN would be displayed to the user and not interceptable by the app.
If you app has moved to the background and is suspended you have no options (apart from APN, but the user will see it).
You can use apple push notification, long polling and websockets, these are the alternatives. Read more here and here.