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¶
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
60seconds.
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¶
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¶
Configures a cron-like automated schedule that tells the SDK when to
start and
stop tracking.
- Times are in 24h format.
DAYuses 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:
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:
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
falseand 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¶
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¶
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