I am designing an app that needs to exchange data in real time over network and I am planning to use socket connection to achieve this. To keep the socket connection open in background I plan to declare my app as a VOIP app (I already know apple's rule prohibiting this and willing to take the risk), and use keepAliveTimeout to keep connections alive.
Now can I declare and own a socket which will listen to any incoming data or I have to use an existing/specific socket given by Apple? Also is the port unique per app or per phone? Means if my app is continuing in background and also a call comes over Skype would they interfere with each other?
Thanks in advance for response. Help would be appreciated.
Related
The iOS APIs allow me to open listening sockets for example using the ServerSocket class, however if my App is not in the foreground I assume I won't receive any requests sent to the socket. Is there a way I can keep the listening socket open in the background? Thanks!
Having researched this further I am now convinced that listening sockets on iOS in most circumstances are only useful if your app is the foreground.
The only methods I have found that allow a persistent listening socket in the background abuse other parts of the API e.g. location API so are not suitable for anything beyond an academic demonstration of the capability.
I'm trying to connect to our push server via MQTT-Client-Framework.
There is no complication for connecting to server and with a few line of code i can connect to server and subscribe to topic.
but I have a few question that I could not find any direct answer for them.
1) How can I keep my client running at background?
2) What happen after device restart? how can I automatically connect to server after device restart?
3)Suppose I got an error during connecting to server. Will this library trying to connect in a loop? how many times it try? or I need to manage this myself?
4) The same 3 scenario for subscribing to topic?
Based on my experience on MQTT-client framework following are the answers to your questions/queries. I hope it clarifies your concerns and helps you to move ahead.
1) How can I keep my client running at background?
You can not keep your MQTT client running in background, as Apple doesn't allow any application to keep running for long time in background. Though if you override its not guaranteed your application will keep running in background. You can read more about background execution support in apple documentation.
Also refer issue posted on github for given framework.
2) What happen after device restart? how can I automatically connect to server after device restart?
Each time your app begin execution you need to connect to your server using MQTT client framework there is no auto connect mechanism available in MQTT-client framework. I suggest to write init your connection in specific controller which executes immediately after your app launch except same as AppDelegate
3) Suppose I got an error during connecting to server. Will this library trying to connect in a loop? how many times it try? or I need to manage this myself?
If your MQTT-client fails to connect your server, you need to handle it yourself, library doesn't try to auto connect as mentioned in previous answer. I have written sample code as below. Use NSTimer for auto connect to server.
[self.mqttSession connectToHost:MQTT_HOST port:MQTT_PORT usingSSL:NO connectHandler:^(NSError *error)
{
if(error)
{
// Application fail to connect to server, write your code to auto connect here
}
}];
4) The same 3 scenario for subscribing to topic?
If your broker server has configuration to track your existing subscription for individual users/client then you don't need to subscribe each time.
Otherwise each time you need to subscribe to same topic on successful connection. Use following MQTTSessionDelegate method to subscribe.
- (void)connected:(MQTTSession *)session
Happy coding :)
1)Project->Capabilities->Background Modes. There has some options for allowing your app to run at background.
2)Generally speaking, MQTT will not be disconnected to the server if your app is allowed to run at background, but i think you would better check up the connection and maybe re-connect MQTT to your server when the app become active again.
AppDelegate-> - (void)applicationDidBecomeActive:(UIApplication *)application;
3)Unfortunately, yes, it will. And you have to manage yourself.
4)I can't help.
For your first question:
Details on how to run in the background on iOS can be found here. This link also lists the actions that Apple allows to run in the background, if your app does not meet those criteria then it is likely to get thrown out of the app store by Apple.
The list also shows which UIBackgroundModes to place in your Info.plist to flag that your app needs background access.
The other 3 I can't help with
We all know that Apple doesn't allow app service to run in the background, so MQTT will be disconnected in the background mode.
Now do one thing use better frameworks for MQTT like this in this framework you will get auto-reconnect and callbacks and many things.
So When you receive a call back that the MQTT is connected, immediately subscribe to all the topics that you have.
And if you want to get all missed messages then you need to change the MQTT configuration to like 'clean = false'.
I have a navigation application that works with both CoreLocation (Backgrounding mode Location updates) as well as GPS data provided over a UDP connection from an external sensor.
I've noticed that when I background the app the socket goes down (which likely makes sense).
What is the procedure to keep the socket open in backgorunding?
Idea
I thought perhaps to register as a VoIP app - would keep the socket open but it looks like that works differently now.
The documentation suggest implementing setKeepAliveTimeout:handler: but this appears to be deprecated.
I'm not sure exactly how to proceed. Any ideas? The best I can come up with is a hack to have my location-update handler run a check on the socket so see if there is new data - but I'm assume there is a legitimate way to do this.
When the phone goes in stand-by all the UDP socket are closed and only TCP connection can be used. Yes probably with VOIP app you can use the UDP but in that case your app will be reject because your don't use a real VOIP service. I had the same problem ... In my case, even if the phone is in background, I want to send UDP message to a domotic system but is not possible.
Apple added in iOS 7 new possibility to execute activities in the background, fetch mode, which can be used e.g. for Twitter, when frequently small amounts of data need to be downloaded (official description: The app regularly downloads and processes small amounts of content from the network.),Apple Document Reference
However, I need to use a TCP connection.
Does anyone know whenever TCP connection may be used in such scenario between the calls?
The scenario is:
I open the TCP socket in the beginning and then the application can use it in these fetch calls. Of course handlers are needed when the TCP connection drops, but there is a difference between rare necessity to reconnect and constant (i.e. in each fetch iteration) need to reconnect.
I am trying to implement an iOS VOIP application.
I am using GCDAsyncSocket to listen on a port for connections. I did add the required background modes in info.plist and also registered the readstream and writestream to kcfNetworkServiceTypeVOIP.
I also added KeepAliveTimeOutHandler to wake up the app. The handler block just prints the wake up time to stdout.
As long as app is in foreground new connections are accepted but when the app is in background, the app is not waken and all the connections attempted are sent to the socket when the app moves to foreground again.
I searched through many solutions but could not get it to work.
Thanks in advance.
I am not sure if it is still relevant for you but in case someone else reads this question.
As discussed in other similar question on stackoverflow in this one for example you can have only one socket which is in NetworkServiceTypeVOIP mode. Otherwise both of them will not work and your app will not wake up and not accept new connections.