Best Practice Guide for Background Location Update with iOS

The primary objective of background location data acquisition of GroundSage is to achieve persistent location data capture of app users for the calculation of GroundSage crowd density information. Once the app using GroundSage SDK is launched within the vicinity of the venue, IndoorAtlas location update will be kept running by the OS for long-lasting data acquisition regardless of the app UI being in foreground or not. The data acquisition will continue until the user closes the app. When the user leaves the vicinity of the venue, the app should stop the persistent location data acquisition in order to save battery and avoid unnecessary location tracking.


  • Get Apple’s approval for declaring support of location in the locationUIBackgroundModes key in Info.plist
    <plist version="1.0">
    <dict>
        ...
        <key>UIBackgroundModes</key>
        <array>
            <string>location</string>
        </array>
        ...
    </dict>
    </plist>
    
  • The app should call UIApplication.beginBackgroundTask()when the app is in foreground so that the task can run in background.
    class AppDelegate: UIResponder, UIApplicationDelegate {
        ...
        var backgroundTaskId = UIBackgroundTaskIdentifier.invalid
        
        func applicationDidBecomeActive(_ application: UIApplication) {
            if backgroundTaskId != UIBackgroundTaskIdentifier.invalid {
                IAGSManager.shared.stopSubscription()
                UIApplication.shared.endBackgroundTask(backgroundTaskId)
                backgroundTaskId = UIBackgroundTaskIdentifier.invalid
            }
        }
    
        func applicationDidEnterBackground(_ application: UIApplication) {
            if backgroundTaskId == UIBackgroundTaskIdentifier.invalid  {
                IAGSManager.shared.startSubscription()
                backgroundTaskId = UIApplication.shared.beginBackgroundTask(withName:"MyBackgroundTask", expirationHandler: {() -> Void in
                    UIApplication.shared.endBackgroundTask(self.backgroundTaskId)
                    self.backgroundTaskId = UIBackgroundTaskIdentifier.invalid
                })
            }
        }
        ...
    }
  • The app should call IAGSManager.startSubscription()of GroundSage SDK upon launch.
      func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            ...
            IAGSManager.shared.startSubscription()
            ...
            return true
        }
  • After calling IAGSManager.startSubscription(), the callback IAGSManagerDelegate.didEnterDensityRegion(_:region:) of GroundSage SDK will get called when the user enters the vicinity of the venue area or is already within the vicinity of the venue at the start of location update. If the app doesn’t receive IAGSManagerDelegate.didEnterDensityRegion(_:region:)in 5 second, it should call stopSubscription.
  • When the user leaves the vicinity of the venue, the app should call IAGSManager.stopSubscription() and UIApplication.endBackgroundTask(_ identifier: UIBackgroundTaskIdentifier). The callback   IAGSManagerDelegate.didExitDensityRegion(_:region:) of GroundSage SDK will get called when the user leaves the vicinity of the venue.