3

I have created an app which tracks the location of the user even if the app is in the background or the screen is locked. I have tested it on an iPhone 5s device with iOS 9.2 and everything was working fine. After updating to iOS 9.3.1 I noticed that the app would run for about 10 minutes in the background and then app would automatically stop. I updated the phone to iOS 9.3.2 yesterday hoping that there was a fix for this issue. However the issue still persists.

I have the following code in AppDelegate class

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

  var window: UIWindow?
  private static var backgroundService : BackgroundService? = nil
  var startServices : Bool = false
  public static var bgTask = UIBackgroundTaskIdentifier()

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    print("didFinishLaunchingWithOptions")

    AppDelegate.bgTask = beginBackgroundUpdateTask()
    startBackgroundService()
    return true
  }

  internal func startBackgroundService(){
    if AppDelegate.backgroundService == nil{
      AppDelegate.backgroundService = BackgroundService.getBackgroundService()
    }
    AppDelegate.backgroundService!.startService(self)
  }

  internal func stopBackgroundService(){
    AppDelegate.backgroundService!.stopService()
  }

  func beginBackgroundUpdateTask() -> UIBackgroundTaskIdentifier {
    return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
  }

  func applicationDidEnterBackground(application: UIApplication) {
    self.startBackgroundService()
    print("applicationDidEnterBackground")
  }
}

Background App Refresh and Location Services have been enabled for the app on the iphone. Background mode has been enabled and other required permissions have been added in Info.plist.

The issue is not due to any code changes as I tested the code on another phone with iOS 9.2 and it is working perfectly. After updating the second phone to iOS 9.3.2 the same issue occurred. Has there been any change in 9.3 which is causing this issue? I went through the changelogs and documentation but haven't been able to find anything useful. Has anyone else encountered a similar issue? Is there any changes that I need to do to ensure that the app works with iOS 9.3?

Joyson
  • 3,025
  • 1
  • 20
  • 34
  • 1
    I suspect that Apple have tightened up the background processing. Using `backgroundTaskWithExpirationHandler` is *not* the right way to get location updates in the background. – Paulw11 Jun 01 '16 at 10:51
  • @Paulw11 - Could you suggest what would be the right way to get the updates in the background? I am new to iOS development and backgroundTaskWithExpirationHandler was the only way I managed to get it working in the background. – Joyson Jun 01 '16 at 11:18
  • Are you used Background modes for Location updates? – Ahmed Abdallah Jun 01 '16 at 11:27
  • @Ahmed - Yes Background Modes for Location updates has been enabled. – Joyson Jun 01 '16 at 11:32
  • You test it more than one time in background mode or not? – Ahmed Abdallah Jun 01 '16 at 11:40
  • Are you set `self.locationManager.allowsBackgroundLocationUpdates = true` – Ahmed Abdallah Jun 01 '16 at 11:43
  • Please take a look at this question: [http://stackoverflow.com/questions/35515528/ios-gps-tracking-app-that-runs-all-the-time/37471850#37471850](http://stackoverflow.com/questions/35515528/ios-gps-tracking-app-that-runs-all-the-time/37471850#37471850) – danywarner Jun 01 '16 at 14:44

2 Answers2

2

Finally managed to solve the issue. After adding locationManager.allowsBackgroundLocationUpdates = true as suggested the issue still persisted. Although it ran in the background for a longer duration but after a certain point the app stopped fetching location data.

After searching online a bit more I came across this setting

locationManager.pausesLocationUpdatesAutomatically = false

Adding this line solved the issue and the location fetching works in the background without stopping abruptly. The default value for it is true.

As mentioned by @Ahmed and @Chajmz allowsBackgroundLocationUpdates is required in iOS 9 and later

In iOS 9 and later, regardless of deployment target, you must also set the allowsBackgroundLocationUpdates property of the location manager object to YES in order to receive background location updates. By default, this property is NO, and it should remain this way until a time when your app actively requires background location updates.

As per the documentation about CLLocationManager - pausesLocationUpdatesAutomatically

Allowing the location manager to pause updates can improve battery life on the target device without sacrificing location data. When this property is set to true, the location manager pauses updates (and powers down the appropriate hardware) at times when the location data is unlikely to change. For example, if the user stops for food while using a navigation app, the location manager might pause updates for a period of time.

The default value of this property is true.

Community
  • 1
  • 1
Joyson
  • 3,025
  • 1
  • 20
  • 34
0

Since iOS 9, you can avoid using backgroundTaskWithExpirationHandler, if you want to have constant access to your data from your LocationManager you can use allowsBackgroundLocationUpdates however, if you stop your LocationManager in background you won't be able to restart it from background.

if #available(iOS 9.0, *) {
     manager.allowsBackgroundLocationUpdates = true
 } else {
      // Fallback on earlier versions
 }
Chajmz
  • 729
  • 5
  • 11
  • You can start it again as long as you have started significant location updates in the foreground – Paulw11 Jun 01 '16 at 12:10