Best practice guide for location data acquisition

Introduction

The primary objective of location data acquisition of GroundSage is to achieve persistent location data capture of app users for the calculation of GroundSage crowd density. 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.

Location data acquisition

  • Get Apple’s approval for declaring support of location in the UIBackgroundModes 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
            })
        }
    }
    ...
}
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        ...
        IAGSManager.shared.startSubscription()
        ...
        return true
    }