I'm currently developing an app where the device's location should be send to a server. I've worked through the MSDN articles on the background agents and accessing the location. This works so far. My location is transmitted to the server when I've triggered a location change which is farther away than the set MovementThreshold.
However, I've read that testing of background agents can be complicated. If you use the Emulator, you can easily change your device's location very often. But on a real phone, location background services are limited in their idle runtime to 30 minutes and execution of commands should only take up to 25 seconds. Background agents can also be disabled by the user from the phone's settings screen. They are also deactivated, when the agent crashes more than two times in a row. Another limitation is that inactive background agents are stopped after 4 hours, if they don't update an apps live tile.
My app updates a live tiles counter, so I think my background agent should be running up to 14 days without restart from my app. I've tested the app from yesterday to today and saw the background agent running (when looked up from the settings). There was also the small dot in the upper bar visible, indicating that a programm is accessing the phones geo location. However, sometimes the dot vanishes and my background agent is killed for no obvious reasons.
Therefore my question are:
How can I reliable test geo location on a real device without the need to travel with phone and attached debugging laptop?
How can I test in a timely manner for the timeout scenarios I've mentioned (30 min, 4hrs, 14 days)?
How can I check for these two crashs of the background agent?
I think I've made some missinterpretations of how WP8 defines Background Agents. The new WP8 background agent for location is only active, when the app is running. This means that the app must not be closed with the back button. However, it can be switched to the home screen with the windows button or with a long hold back button to access other apps from multitasking.
Regarding my questions:
How can I reliable test geo location on a real device without the need to travel with phone and attached debugging laptop?
How can I test in a timely manner for the timeout scenarios I've mentioned (30 min, 4hrs, 14 days)?
I still have no suitable solution. You are somewhat limited to testing with real devices and the necessary time required to test your constraints.
How can I check for these two crashs of the background agent?
I don't know how to check for this programmatically. It may be, that a user can see this crashing app as a blocked app in the list of background tasks of the phone's setting. There should be a way to detect a blocked app from this list with the help from the links I've supplied above.
For my project, I needed a location background agent, which runs even with locked screen or with no open app. Therefore I've used a PeriodicAgent to require the location once every 30 minutes so that I can send it to the server. But be aware that this background agents cannot access your application settings or classes (see Communication between foreground app and background agent).
Related
I am relatively new to iOS development.
I have a requirement wherein it is important for us to notify our server about a client's current IP address. The reason behind this is because our solution needs to know the current IP address of the registered device.
Now ideally we would want to create a service that can run in background (indefinitely), poll the ip Address of the device every 10 seconds, and if it sees that the ip has changed, then call a web service notifying the server about the same. I have the folowing questions based on my limited knowledge:
Apple gives us limited choices for apps that are allowed for running
background threads (VoIP, background download, music playing,
location updates etc.). Unfortunately my use case is not an exact
fit for any of these. Can I still go ahead and somehow accomplish
this?
I have read that iOScan close any background thread if it needs
resources. Although my process is not resource intensive, should I
be worried?
The background mode will only start once my app has been MANUALLY
started. What I mean to say is that suppose I am able to run this in
background, but for this to happen the user has to once start the
app manually after restarting the device. Is there a way to start a
service/thread on restart? Is there a workaround?
You cannot trust IOS to handle this in the BG for you the way you describe it, because there is no good way to have a task run in the BG indefinitely, you might get away with using location services and trigger your IP uploads when a device moves but that will not resolve the situation when the device is stationary and changes IP although that might be a corner case but will surely happen as the device moves from tower to tower on 3/4G networks or between different WIFI networks.
Many questions concerning iOS Location tracking have been asked on here, but recently Apple has updated much of their functionality and so many of the answers are obsolete, my question is specifically targeting iOS 8 and 9.
I am interested in creating a location tracking application which will accurately track the user even when the app is closed. To do this, apple states:
If you leave the significant-change location service running and your
iOS app is subsequently suspended or terminated, the service
automatically wakes up your app when new location data arrives. At
wake-up time, the app is put into the background and you are given a
small amount of time (around 10 seconds) to manually restart location
services and process the location data.
So my understanding is, if you have all of the necesarry permission and plist keys present, the OS will wake up your app and allow you to do something for 10 seconds, or if it needs more time it can:
If an iOS app needs more time to process the location data, it can
request more background execution time using the
beginBackgroundTaskWithName:expirationHandler: method of the
UIApplication class.
Now, this says that if my app needs more time to process the location data, it may start a background task (with an expirationHandler) to handle that. When reading about background tasks, I read that background tasks can run for a maximum of 10 minutes
So my overall question is, when my app gets woken up when a significant location change has occurred, is it possible to start the standard location service and have it run in the background indefinitely? Is it possible to start another background task before the first one expires?
EDIT:
From the Apple Documentation it says:
because it wakes the system and your app at least every 15 minutes,
even if no location changes have occurred, and it runs continuously
until you stop it
So my idea is, if the user starts their phone from nothing and never opens the app, after at most 15 minutes (even if they are standing still), the OS will fire my app, in which case I could start a background process that I can start the GPS tracking in, and thus getting accurate GPS location. Would this logic work with the OS?
The main problem is that significant location changes cannot be used for
"accurately track" the user.
Significant means 1000m, since it is cell tower based, and not GPS based.
So your app is woke up when the user moves into the next GSM cell.
This is not acurate enough for acurate tracking.
finally this means you cannot acuratley track when the app is closed, this works only in running app or background running up.
"When reading about background tasks, I read that background tasks can
run for a maximum of 10 minutes"
No, thats not true. My app runs in background and records GPS locations until the battery is drained (8h+). (It does not use the significant location mode)
Is there any way in latest iOS to initiate location capture at a particular time each day (say morning and evening ), even if the app is in background or not running.
You should read Background execution. Background jobs are actually not recommended:
An app might move to the background because the user launched a different app or because the user locked the device and is not using it right now. In both situations, the user is signaling that your app does not need to be doing any meaningful work right now. Continuing to run in such conditions will only drain the device’s battery and might lead the user to force quit your app altogether.
As for getting user location check this answer How can I get current location from user in iOS
I'm currently working on an iOS app using objective-C that send every minute gps coordinates to my API.
I've used AFNetworking & CoreLocation, I also wanted my App to run all day long, but only send coordinates if time is between 8am - 6pm.
Everything's working fine on iOS simulator targetting iOS9 my app is sending his location every 1 minute to my API, even if i press home or lock the phone.
PhoneCall, loss of network or GPS have been handled in order to keep my task running.
But when I tested it on some device (iPhone 4S on iOS9) Location stop updating after an average time of 1hour to 1hour and a half.
Is iOS shutting down my app in background after a given time?
If so, is there a way to keep my app doing her job in background for at least 10 hour, without having to prompt the device user?
Implementing long running background task are "allowed" by apple if it concern:
"The app keeps users informed of their location, even while it is running in the background."
Does that mean background task will block my http request after a while?
For long term deployment, I wish my app to be upload on the App Store, but I've read many post about app GPS tracking app which have been rejected.
Here's the minimal list of requirement my app should have:
Send GPS coordinates to my API every minute
Working in background for a minimum time of 10 hours without shutting down or prompting user to reload the view
Could those requirement be accepted to get my app upload on AppStore?
Or will I have to use local/remote notification and prompt the user to reload my app in order to keep it running for such a long time?
The documentation says.
The significant-change location service is highly recommended for apps that do not need high-precision location data. With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social apps or apps that provide the user with noncritical, location-relevant information. If the app is suspended when an update occurs, the system wakes it up in the background to handle the update. If the app starts this service and is then terminated, the system relaunches the app automatically when a new location becomes available. This service is available in iOS 4 and later, and it is available only on devices that contain a cellular radio.
I think this will be apt for your scenario.
I'm spec-ing an iOS app (which will be built outside of our company) which will upload a user's data entry to a server. If the device is not connected to the Internet, we'd like to save data on the device and upload it when the network is re-connected. (The app will primarily run on iPod Touch devices that will be disconnected most of the time).
If the user unlocks the device and re-opens our app after the network is reconnected, then uploading to the server should be easy because the app is running.
But what if the app is not running, where "not running" can mean one or more of:
device was power cycled
user has locked the device and it's sitting in his pocket
app crashed
user exited the app
user started using other apps so our app isn't running in the foreground anymore
are there other cases?
In the cases above, is there a way (ideally a battery-efficient way) to ensure that local data is uploaded soon after Internet connectivity is restored? Is the answer different depending on which of the cases above caused the app not to be running?
And is there a minimum iOS version the device will need in order to enable some (or all) of the above not-running cases to still upload when the app is not running?
My apologies if these are obvious newbie questions-- I'm not an iOS expert.
There is an interesting technique that is used by among others Instapaper and News.me(the pioneers of this technique) where you use region monitoring to initiate background downloads or uploads. Marco (Instapaper) blogged and talked (in episode 80 of the Build and Analyze podcast) about his communication with Apple so it should be a allowed in the App Store.
In brief the technique is that you set up certain regions (geofences) like "home" or "work" and respond to the locationManager:didEnterRegion: (and similar) callback(s). Your app will wake up from the background once you enter the pre-specified region and you can check to see if there is any data to upload.
This technique won't guarantee that the data is uploaded when the network reconnects but it will allow your app to automatically upload the information when the iPod Touch users gets home to their WiFi network.
That should most likely be at least once a day which may or may not be frequent enough for you. You could add a timestamp to when the initial upload was attempted and send that along the upload once it succeeds to get the correct order of events (data entries) on your server.
There is no way to ensure this. If your application is "not running" (by the definition described in your question), it will not be capable of responding to a change in the device's network status. It should be setup to resume upload operations the next time the application runs again.
EDIT:
Some of the cases you've described may indeed provide different opportunities for your application. Specifically, if the user "exits" the app by pressing the home button or launches another app in the foreground, your application may continue to run the in the background and could potentially respond to a change in network reachability.
The nature of what may be done in the background and for how-long is well documented, and supported by any version of iOS that supports multi-tasking. I recommend you review the documentation pertaining to App States and Background Services.
device was power cycled --> really NO WAY of resuming, unless you open the App!!!
user has locked the device and it's sitting in his pocket --> apps applicationStatus is UIApplicationStateInactive but it is running in the background. You still are able to react to notifications and i.e. accelerometer events. Try the Reachability Class and Log the changes!
app crashed --> NO WAY, unless opening the App
user exited the app --> App is sitting in the background. There you have a maximum of 10 Minutes Restriction of fully using your App (like the App "Pastebot" does)
user started using other apps so our app isn't running in the
foreground anymore --> Same as user exited the app
On multitasking Apple says the following:
Real multitasking only for certain kinds of usage, as there is Audio Background playing, VOIP (like Skype), navigation applications
All the other apps can request a specific amount of time after the app is closed/in the background, to finish certain tasks (as sending an email, sms or uploading/downloading important data)
Important Quote from dev docs:
Your app delegate’s applicationDidEnterBackground: method has approximately 5 seconds to finish any tasks and return. In practice, this method should return as quickly as possible. If the method does not return before time runs out, your app is killed and purged from memory. If you still need more time to perform tasks, call the beginBackgroundTaskWithExpirationHandler: method to request background execution time and then start any long-running tasks in a secondary thread. Regardless of whether you start any background tasks, the applicationDidEnterBackground: method must still exit within 5 seconds.
If you're building a restful API then I would recommend using RestKit, it has a request queue that checks the network status on the device and starts uploading once network access has been assured. You can read more about this here: http://mobile.tutsplus.com/tutorials/iphone/advanced-restkit-development_iphone-sdk/. Read the sections about Request Queue and background download/upload. It should be noted that RestKit is a big library which has it's advantages and disadvantages. I'm not completely sure how this que works with the app lifecycle, if it saves the request que even if the app is terminated. You would have to investigate that. RestKit does support background uploading/downloading, but as already noted, I think it's impossible to do any uploading if the app is terminated and not in background state.
I wouldn't recommend using RestKit if the API isn't Rest though.
You can download and experiment with RestKit here: https://github.com/RestKit/RestKit.