Forum Xamarin.iOS

IOS7 Location Service not working in Background anymore

Good day,
Since I've updated my phone to IOS7 my app does not update location data anymore when running in the background.
Everything is correctly set in the plist and it worked 100% on IOS6.
Location updates is received when app is running in foreground, but when app is minimised it stops getting location data until it is in the foreground again.

Any idea why this is happening and how one can fix this.

Thanks

Posts

  • HtunHtikeHtunHtike SGMember

    Any update on this? I am also facing same issue.

  • rrodriguezrrodriguez USMember

    Sorry for reviving this old thread. I have the same problem.

    In my app I need to report the user position after x feet movement. There is no requirement for frequency, so if the user is stationary I don't have to report the same position several times; same if the user moves within a radius that is considered "irrelevant" due to the x feet restriction.

    After googling for a while I found this blog post and this related SO answer and I was wondering how you guys handled this issue.

    The way I see it I have some options:

    1) The approach taken by the aforementioned blog post in which a timer would "wake up" the location service by turning it on for some time (10 seconds) every minute or so. The author is reporting 5% battery consumption per hour.

    2) The significant-change location service approach, combined with a finer grain location updates. This way the significant-change would force the application to resume and even initiate it if a "significant" movement is detected.

    3) Set the pausesLocationUpdatesAutomatically property to TRUE in the core location manager.

    For some reason I'm not completely sold on any of the alternatives I see.

    In 1) I'm not happy with the battery usage; not sure if I'm being too picky.

    In 2) the "significant" change can be too big for some of my users (some of them want the app to report the position on 100 feet movements); so I can't afford having big gaps in the breadcrumb trail.

    I'm not sure about 3) when it comes to battery usage.

    Thanks in advance for any input you can provide.

    R.

  • rrodriguezrrodriguez USMember

    Bump! Any inputs? Thanks in advance!

  • JahmaiJahmai AUMember ✭✭

    If your app is in the background and location services are turned off, your app will likely immediately be suspended.

    That means no timers will run, so you cannot schedule some callback to turn location services on again.

    In iOS 6, you could use "background tasks" to allow your app to run in the background for up to 10 minutes. You could use (exploit) this to essentially keep your app running perpetually by starting a background task, stopping location services, (wait 10 minutes), start location services and stop the background task. The background task timer resets at this point and so you could rinse and repeat.

    In iOS 7, Apple 'fixed' this by changing the way background tasks function in that you are not guaranteed 10 contiguous minutes of background time. Instead, as soon as you move into the background, your app may be suspended. The OS then decides when to give your app a slice of that 10 minutes background time, which likely coincides with the user interacting with the phone (i.e. the screen is on). Very unpredictable and kind of useless IMO.

    Therefore the only reliable way to manage power consumption of location services while the app is in the background is to put the location manager on the lowest possible required accuracy during your 'conservation period', and increase it's accuracy when you need it.

    I've never had much luck with pausesLocationUpdatesAutomatically, in that it often never comes back on after it has been paused.

    I haven't used the significant changes function because our app actually needs fine grained location on demand.

  • @rrodriguez Did you find a solution for the background location updates?

  • rrodriguezrrodriguez USMember
    edited April 2014

    @Jahmai‌ thanks for your input man, for some reason I was never notified of your answer. Wouldn't iOS still put suspend (and kill) the app while in the background regardless the accuracy I set it for? I'm confused.

    @MortenKruse‌, no man... I just put this on hold for a while. I'm finishing a higher priority feature in the app now and will resume with location afterwards. I will keep this thread updated with the results.

  • JahmaiJahmai AUMember ✭✭

    @rrodriguez‌

    Sorry I should have used the @ function to get your attention on my last post.

    As long as you have the Background Location permission on the app (subject to AppStore approval process), and you are actually using location services (you have called LocationManager.StartUpdatingLocation()), your application will stay alive indefinitely, even in the background.

    The moment you call LocationManager.StopUpdatingLocation(), and you move into the background (or you call it while you are running in the background), your app will be suspended. Except if you have a background task active as per my previous post - but once the background task ends and location services has not been restarted, you are unable to execute any more code.

    Keep in mind that even on the lowest location accuracy, you'll pretty much deplete an iPhone battery within a day or so. Our application is safety oriented app, so users are typically OK with this behavior and some even have extended battery packs specifically for our apps.

  • rrodriguezrrodriguez USMember

    @Jahmai‌ our app is using location services and it is approved in the app store.
    It does tracks the location perfectly while in the foreground; and in the background too, providing the user keeps moving. As soon as the user remains stationary for a while, it seems that iOS is suspending our app due to the lack of new positions being reported.

    This behavior is described here: http://stackoverflow.com/questions/18946881/background-location-services-not-working-in-ios-7/21966662#21966662

  • JahmaiJahmai AUMember ✭✭

    @rrodriguez‌

    As I said, using a background task is not enough of a guarantee to be able to run timers and such in iOS 7.

    To be clear, in iOS 7, as soon as the phone goes 'idle' (typically when the screen locks) then your app may be suspended even if you have a background task running. This is contrast to iOS 6 where you were guaranteed 10 minutes of consecutive time.

    This is vaguely what we do, except we do quite a lot of optimizing of the accuracy and time periods depending on battery availability and application state:

    private void StopUpdatingLocation()
    {
        using (UIApplication.SharedApplication.BeginScopedBackgroundTask())
        {
            LocationManager.StopUpdatingLocation();
            LocationManager.DesiredAccuracy = CLLocation.AccuracyThreeKilometers;
            LocationManager.StartUpdatingLocation();
        }
    
        Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(task => StartUpdatingLocation());
    }
    
    private void StartUpdatingLocation()
    {
        using (UIApplication.SharedApplication.BeginScopedBackgroundTask())
        {
            LocationManager.StopUpdatingLocation();
            LocationManager.DesiredAccuracy = CLLocation.AccuracyBest;
            LocationManager.StartUpdatingLocation();
        }
    
        Task.Delay(TimeSpan.FromMinutes(1)).ContinueWith(task => StopUpdatingLocation());
    }
    

    Note that our background task lives just long enough to turn location services on and off (probably less than a millisecond of execution time).

  • JahmaiJahmai AUMember ✭✭

    Note that in the above code 'LocationManager' is actually a special member that does appropriate threading calls to an instance of CLLocationManager, so don't expect it to copy-paste work.

  • rrodriguezrrodriguez USMember

    @Jahmai do not worry, no copy&paste work intended.

    Based on your previous input:

    As long as you have the Background Location permission on the app (subject to AppStore approval process), and you are actually using location services (you have called LocationManager.StartUpdatingLocation()), your application will stay alive indefinitely, even in the background.

    This is not accurate, according to the behavior I'm seeing and what is reported by other developers (ie: the SO link I provided).

    So, they question here is "How do I prevent my application from being suspended even when the user remains stationary?"

    I'm using the location service, which in theory is supposed to prevent your app to be suspended. But it is clear that iOS is killing the app if, after certain amount of time, the user hasn't moved and no location changes are reported by the location service.

    I'm not using a background task, I was just wondering if using a background task (just as you included in your latest post) would help me circumvent the limitation I'm seeing on iOS.

    I want my app to gather significant movements (not in alignment to what "significant" means in the Significant-Change Location Service unfortunately). If my app user is surveying or doing any activity in the field, I want my app to track his position, if he spends an hour working in a single location I don't want my app to be suspended due to this, instead I expect my app to continue tracking his position once he resumes his work and moves to a different location.

    Thanks for your input!

  • JahmaiJahmai AUMember ✭✭

    @rrodriguez‌

    I know what I am saying is accurate because our apps work in this fashion, and it doesn't matter if they sit at a desk all day long.

    That SO link you provided showed code that stopped updating location and used a background task and a timer to restart it, which is exactly the thing I say you are unable to do any more.

    And as I said much earlier in this thread:

    I've never had much luck with pausesLocationUpdatesAutomatically, in that it often never comes back on after it has been paused.

    So if you are still using that function I would expect nothing less than your app to be suspended.

    At this point to help you further I would have to see your code.

  • JahmaiJahmai AUMember ✭✭

    BTW I realize this is frustrating. It took us quite a lot of experimenting to discover the trick with iOS 6 where we could cycle location services on and off and keep our app running. iOS 7 changed all that for us and was quite painful ensuring our apps still behaved the same way. But rest assured it does work if you are willing to pay the battery usage cost of having location services on all the time.

  • DKurkinDKurkin GBMember ✭✭

    @rrodriguez‌
    Also working on same issue.
    This is 1 month old thread but just want to add to the topic some info I found on the net.
    http://stackoverflow.com/questions/23120125/updating-location-from-the-background-in-ios-7
    On the link is the discussion of the same problem with sample code and implementation in native Obj-c.
    I am testing the solution at the moment to proof the concept is working.

    That could be used in Xam project too

  • realpaplarealpapla SEMember

    @Jahmai ,
    I have tried quite hard now to get location updates every second (or every second with a distance filter of 10m). I need this for my alpine skiing app that I try to develop for my skiing club. I wonder if you could give me some example where I get these updates even if the app is not in the foreground.

Sign In or Register to comment.