Skip to content

AppConfig

public classAppConfig

Application and lifecycle configuration for the background geolocation SDK.

AppConfig controls how the SDK integrates with your app's lifecycle: tracking behavior on terminate and reboot, headless operation, periodic heartbeats, automated scheduler windows, foreground notifications, and the Android background-permission rationale dialog.

Contents

Overview
Category Properties Notes
Lifecycle stopOnTerminate, startOnBoot Controls tracking across app terminate and device reboot.
Headless enableHeadless Android only Tracking continues with no JS/UI process.
Heartbeat heartbeatInterval, preventSuspend Periodic background callbacks. preventSuspend is iOS only.
Scheduler schedule, scheduleUseAlarmManager Automated start/stop windows. scheduleUseAlarmManager is Android only.
Notification notification Android only Foreground service notification.
Permission backgroundPermissionRationale Android only Android 11+ background location rationale.
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.stopOnTerminate = false
    config.app.startOnBoot = true
}

Lifecycle

AppConfig.stopOnTerminate (default true) controls whether tracking stops when the user terminates the app. Set to false to continue tracking after termination — iOS and Android handle this differently:

  • iOS creates a stationary geofence and relaunches the app when the device exits it (~200 m). Tracking resumes automatically.
  • Android continues the native background service headlessly. Pair with HttpConfig.url to ensure uploads continue without the UI layer.

AppConfig.startOnBoot (default false) controls whether tracking resumes after a device reboot. On Android, the background service restarts automatically. On iOS, the OS must first wake the app via a stationary geofence exit or a Background Fetch event.

AppConfig.enableHeadless (default false) allows Android to respond to SDK events even after the app is terminated. Requires stopOnTerminate: false. Android only


Heartbeat

AppConfig.heartbeatInterval fires BGGeo.onHeartbeat periodically while the app is in the background. On iOS, this requires AppConfig.preventSuspend true to keep the app alive. On Android, the minimum interval is 60 seconds.

AppConfig.preventSuspend (default false) prevents iOS from suspending the app when location services are inactive. Required for heartbeat support on iOS but increases battery consumption — use only for specific, time-limited use cases. iOS only


Scheduler

AppConfig.schedule accepts an array of schedule strings that tell the SDK when to automatically start and stop tracking. Each string follows the format "DAY(s) HH:mm-HH:mm" using 24h time and Locale.US day numbers (Sunday=1, Saturday=7).

Call BGGeo.startSchedule to activate the scheduler after calling ready().

AppConfig.scheduleUseAlarmManager (default false) forces the Android scheduler to use AlarmManager (exact, on-the-minute) instead of JobScheduler (inexact). Android only


Background permission

Android 11 removed the Allow all the time option from the system location dialog. Configure AppConfig.backgroundPermissionRationale to show a custom rationale dialog that routes the user to the system Location Permissions screen to grant background access. The SDK shows this dialog automatically when GeolocationConfig.locationAuthorizationRequest is "Always". Android only

See PermissionRationale for the full dialog configuration reference.


Examples
Configure once at startup:
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.stopOnTerminate = false
    config.app.startOnBoot = true
    // enableHeadless — Android only — not applicable on iOS
    config.app.heartbeatInterval = 60
    // backgroundPermissionRationale — Android only — not applicable on iOS
    // notification — Android only — not applicable on iOS
    config.app.schedule = ["1-5 09:00-17:00"] // Weekdays 9-5
    // scheduleUseAlarmManager — Android only — not applicable on iOS
}
Update later at runtime:
let bgGeo = BGGeo.shared
bgGeo.config.batchUpdate { config in
    config.app.heartbeatInterval = 120 // slow down heartbeats
}

Members

heartbeatInterval

public var heartbeatInterval: TimeInterval

Rate in seconds at which BGGeo.onHeartbeat events fire while the app is in the background.

iOS

Requires AppConfig.preventSuspend true. Defaults to 60 seconds when enabled.

Android

Heartbeat is disabled by default (-1). Set to a positive integer of at least 60 to enable it. Values below 60 are not supported.

Warning

  • On iOS, heartbeat fires only when AppConfig.preventSuspend is true.
  • On Android, the minimum supported interval is 60 seconds.

See also - BGGeo.onHeartbeat

let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.preventSuspend = true
    config.app.heartbeatInterval = 60
}

bgGeo.onHeartbeat { event in
    print("[onHeartbeat]", event)

    // Optionally request a new location during heartbeat.
    Task {
        do {
            let location = try await bgGeo.getCurrentPosition(samples: 1, persist: true)
            print("[getCurrentPosition]", location)
        } catch {
            print("Error: \(error)")
        }
    }
}

preventSuspend

public var preventSuspend: Bool

iOS only Prevents iOS from suspending the application after location services have been disabled while running in the background. Defaults to false. Set to true to keep the app alive in the background even after iOS disables location services. This is required for AppConfig.heartbeatInterval to fire on iOS.

Warning

preventSuspend: true has a large and noticeable impact on battery consumption. Use it only for specific, time-limited use cases — it is not suitable for continuous 24/7 operation.

When the device is unplugged with the screen off, iOS still throttles heartbeat events approximately 2 minutes after entering the background. Heartbeats resume immediately when the screen turns on or any device motion is detected.

See also - AppConfig.heartbeatInterval - BGGeo.onHeartbeat

let bgGeo = BGGeo.shared

// Subscribe to heartbeat events
bgGeo.onHeartbeat { event in
    print("[onHeartbeat]", event)
}

// Enable preventSuspend via AppConfig
bgGeo.ready { config in
    config.app.preventSuspend = true
    config.app.heartbeatInterval = 60
}

schedule

public var schedule: [Any]

Configures a cron-like automated schedule that tells the SDK when to start and stop tracking.

"DAY(s) START_TIME-END_TIME"
  • Times are in 24h format.
  • DAY uses Locale.US day numbers: Sunday = 1, Saturday = 7.
  • Day values may be a single day ("1"), a comma-separated list ("2,4,6"), or a range ("2-6").
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.schedule = [
        "1 17:30-21:00",     // Sunday: 5:30pm-9pm
        "2-6 09:00-17:00",   // Mon-Fri: 9am-5pm
        "2,4,6 20:00-00:00", // Mon, Wed, Fri: 8pm-midnight
        "7 10:00-19:00"      // Saturday: 10am-7pm
    ]
}

// Start the Scheduler
bgGeo.startSchedule()

// Listen for schedule state changes
bgGeo.onSchedule { event in
    print("[onSchedule] enabled? \(event.enabled)")
}

// Later (e.g., user logout)
bgGeo.stopSchedule()
bgGeo.stop() // if tracking is currently enabled

// Modify schedule using batchUpdate
bgGeo.config.batchUpdate { config in
    config.app.schedule = [
        "1-7 09:00-10:00",
        "1-7 11:00-12:00",
        "1-7 13:00-14:00",
        "1-7 15:00-16:00",
        "1-7 17:00-18:00",
        "2,4,6 19:00-22:00"
    ]
}
Literal dates

A schedule entry may use a literal date range:

"yyyy-mm-dd HH:mm-HH:mm"
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.schedule = [
        "2018-01-01 09:00-17:00"
    ]
}

Or specify distinct start and stop dates:

"yyyy-mm-dd-HH:mm yyyy-mm-dd-HH:mm"
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.schedule = [
        "2018-01-01-09:00 2019-01-01-17:00" // track for 1 year
    ]
}
Scheduling modes

Append geofence or location to explicitly choose a tracking mode.

let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.schedule = [
        "1-7 09:00-17:00 location",
        "1-7 18:00-12:00 geofence"
    ]
}
iOS
  • iOS cannot evaluate the schedule exactly at the configured time. Evaluation occurs only when the app is awakened.
  • During a scheduled off period, iOS continues monitoring low-power Significant Location Changes (SLC) to guarantee periodic re-evaluation, especially when AppConfig.stopOnTerminate is false and the OS halts traditional Background Fetch.
  • Schedule evaluation occurs when the app pauses/resumes, any location is recorded (including SLC), or a Background Fetch event fires.
Android

Uses AlarmManager.setExactAndAllowWhileIdle, typically evaluating on-the-minute.

See also - BGGeo.startSchedule - BGGeo.stopSchedule

Since location is the default mode, it may be omitted
let bgGeo = BGGeo.shared
bgGeo.ready { config in
    config.app.schedule = [
        "1-7 09:00-17:00 location",
        "1-7 18:00-12:00 geofence"
    ]
}

startOnBoot

public var startOnBoot: Bool

Controls whether tracking resumes automatically after the device reboots. Defaults to false.

iOS

iOS cannot begin tracking immediately after a reboot. Similar to AppConfig.stopOnTerminate false, the SDK waits until one of the following occurs: - The device exits the stationary geofence created around the last known location. - A system Background Fetch event fires (typically every ~15 minutes).

Android

When true, Android relaunches the SDK background service after reboot and initial device unlock. If AppConfig.enableHeadless is also true, tracking resumes even before the JS/UI layer starts.

See also - AppConfig.enableHeadless - AppConfig.stopOnTerminate

stopOnTerminate

public var stopOnTerminate: Bool

Controls whether tracking stops when the application is terminated by the user. Defaults to true.

When true, the SDK calls stop() as the app terminates. Set to false to keep tracking alive after termination — iOS and Android behave differently in this state.

iOS

Before termination, the SDK registers a stationary geofence of GeolocationConfig.stationaryRadius meters around the last known position. When the device exits that geofence (~200 m), iOS fully relaunches the app in the background and tracking resumes automatically. This mechanism survives device reboot because iOS monitors geofences at the OS level.

Demo video: https://www.youtube.com/watch?v=aR6r8qV1TI8&t=214s

Android

Android does not pause tracking when the user terminates the app. The native background service continues running headlessly without the JS/UI process. Configure HttpConfig.url so the service can continue uploading locations to your server.

See also - AppConfig.enableHeadless - Android Headless Mode