I developed and app that is currently set as "Location based" so that it can run in the background indefenitely. It's not a trick i need it to do stuff when the user moves.
After some search I learned that this app will only execute code on the event of a location change, no timer whatsoever will be able to execute any code after 10 mins.
My app, while in the background, stays connected to XMPP for 50mins or so, it then disconnects. I would like the app to never disconnect, I looked at the framework but I can't find the place where to fix this behaviour. Do you know if it's possible to stay connected "indefinetly"? if so what settings do I have to change in the xmppframework.
thanks
[EDIT]
After 50mins the user is still connected to XMPP but it's disconnected of the XMPPRooms it was conected.
On another run it was connected for 3 hours, the time the iPhone is connected doesnt seem to be consistent.
To make sure your application can do send and receive keep-alive messages, it needs to be a voip app and use a voip socket. From Apple's Documentation:
Add the UIBackgroundModes key to your app’s Info.plist file. Set the value of this key to an array that includes the voip value.
Configure one of the app’s sockets for VoIP usage.
Before moving to the background, call the setKeepAliveTimeout:handler: method to install a handler to be executed periodically. Your app can use this handler to maintain its service connection.
As for the socket:
NSInputStream and NSOutputStream: For Cocoa streams, use the setProperty:forKey: method to add the NSStreamNetworkServiceType property to the stream. The value of this property should be set to NSStreamNetworkServiceTypeVoIP.
Related
Is it possible to get a notification (that launches the app) when the network gets available?What I want is my application to update its contents as soon the internet gets available.The only way I can think of is to send a push from the server once is a while (may be once a day)and that tell the user it might be a good idea to get yourself synchronized.
This is currently impossible if your background task scope is limited to that feature. The only way you could do this is if you had some other legitimate reason to become a background app (aka VOIP or GPS) and run reachability checks every X minutes, and then post a UILocalNotification that allows the user optionally open the app (you cannot programmatically open your app yourself).
I'm writing an application that needs once in a while to update the server about the user's location while the application is running in the background. I know I can do this by using the setKeepAliveTimeout:handler: method. I know that this method is specially for VoIP application but I was wondering if Apple will allow this usage for location update to server?
The documentation says that your handler only get 10 seconds to keep the network connection alive for voip calls when using setKeepAliveTimeout:handler: method. See this answer.
This call is for voip apps and you must have voip in your UIBackgroundModes key (info.plist). Using this would probably get rejected unless you are writing a voip app.
You don't need this setKeepAliveTimeout.
I recommend to read this Apple's officatin documentation:
https://developer.apple.com/library/ios/documentation/userexperience/conceptual/LocationAwarenessPG/CoreLocation/CoreLocation.html
One of the things, which iOS provide is a callback on a location change. Your application will be awoken for short period of time and you will receive this callback and should be able to send your location to the server.
BTW. You will need location backgrounding mode for this.
And progmr is right. You will need voip backgrounding mode to use setKeepAliveTimeout. And if your application isn't a real voip application, almost guaranteed that your app will be rejected.
Is it possible to have an iPhone app which carries on listening for data on a port when it is sent to background by the user and if any data comes the app can show a local notification and alert the user? I know the multitasking is deliberately limited but wof it allow for that?
It can but with major caveats:
First, the system will unregister any Bonjour names you might have established.
Second, if you're bound to the WWAN, it will go down even with you listening on it (this is true even in the foreground).
Third, if your app is not doing anything else in the background (i.e., isn't registered to provide background music, location events or telephony), you must still shutdown within the time limit for background task completion or be terminated.
So, while you could bind and listen on a socket in the background, for almost all practical purposes, it's not worth doing and you should rethink your design.
This is exactly what push notifications are for. Your application doesn't listen to your server, your server tells Apple's about any notifications, and Apple's server delivers them to the user and your application if the user wants them.
I'm reading through the multitasking documentation, and it has a few references to apps which launch directly into the background state, never entering the foreground state. Is this really allowed for regular apps? Can anyone give me an example of an app like this?
VoIP apps are the biggest one to use this feature. Basically a VoIP app can register itself with the system to be notified when network traffic is intended for it at which point the app takes over handling the incoming traffic (i.e. receiving a call). Skype and Viber both use it.
From the iOS Developer Library (emphasis mine):
Including the voip value in the
UIBackgroundModes key lets the system
know that it should allow the
application to run in the background
as needed to manage its network
sockets. An application with this key
is also relaunched in the background
immediately after system boot to
ensure that the VoIP services are
always available.
The significant location changes backgrounding service also allows an app to be updated with the new location even if it's not running.
Other than those two cases, an app can't do anything from a terminated state until the user launches it.
When you use location manager with significantchange notification, App gets backgrounded automatically if the app is killed, when there is a location event
My application needs Internet Connection. It seems like if I keep my iPhone idle for a while it shuts down its 3G connection. Once I wake it up (slide to unlock) and run my application, it cannot connect to the Internet. I have to run Youtube or Safari first, then it gets the Internet connection, then I have to shut down Youtube/ Safari and then I can use my application to login to my service.
Could you please let me know how can I activate 3G connection from my application (so that I can use my application directly after it wakes up from the idle state and I do not have to run other applications like Youtube/ Safari?
Thanks.
To disable the idle timer, take a look at the idleTimerDisabled property of the UIApplication class.
From Apple:
The default value of this property is
NO. When most applications have no
touches as user input for a short
period, the system puts the device
into a “sleep” state where the screen
dims. This is done for the purposes of
conserving power. However,
applications that don't have user
input except for the
accelerometer—games, for instance—can,
by setting this property to YES,
disable the “idle timer” to avert
system sleep.
Important: You should set this
property only if necessary and should
be sure to reset it to NO when the
need no longer exists. Most
applications should let the system
turn off the screen when the idle
timer elapses. This includes audio
applications. With appropriate use of
Audio Session Services, playback and
recording proceed uninterrupted when
the screen turns off. The only
applications that should disable the
idle timer are mapping applications,
games, or similar programs with
sporadic user interaction.
There is obviously another better solution, but you could load a blank page with:
[NSString stringWithContentsOfUrl ... ]
The connection will be established if it is necessary.
Only NSURLConnection (and any APIs that are layered on top of it) reinitializes the data connection after waking from sleep. To reinitialize the data connection create a dummy NSURLConnection to a non-local address and cancel it right away; then the socket API will work as expected.
There is a post on the developer forums where an Apple dev explains this in detail (but I can't find it at the moment)
Are you sure you're establising the connection correctly? My application does the same using sockets and it has no problems to re-establish the connection after device sleep. Use Reachability API in SystemConfiguration framework to get notified when coverage is available and after that make your connection attempt. Note that a time period - from several seconds to couple of minutes - has to elapse after the device awakes to gain Internet connectivity, so be patient.
There is Reachability sample from Apple, search also stackoverflow for reachability and you'll find more hints how to implement it.
Actually, you get the same problem when you change the network settings on your phone between launches of the application. For instance let's say that you use the WIFI connection when you launch the app. Then you close the app and switch off the WIFI so that the device uses the carrier's network. When you relaunch the app the socket won't be able to connect unless you do the trick with the dummy NSURLConnection (or you launch the browser before lanuching the app).
Also, canceling the NSURLConnection right after initializing it (with connectionWithRequest or initWithRequest) did not work for me. Either do not cancel the request or wait some time before canceling it (e.g. with performSelector:withObject:afterDelay:).