PersistenceConfig¶
public classPersistenceConfig
Persistence and storage configuration for the background geolocation SDK.
PersistenceConfig controls how the SDK stores, orders, templates, and purges
records in its on-device SQLite database — the durable buffer between data
producers (locations, geofences) and consumers (your app and the HTTP service).
Contents¶
Overview¶
The SDK maintains an internal SQLite database as a rolling queue. Each recorded LocationEvent and geofence event is written immediately, then consumed and deleted by downstream services. The SDK prefers an empty database — records exist only while awaiting upload or retrieval.
| Category | Properties | Notes |
|---|---|---|
| Retention | maxDaysToPersist, maxRecordsToPersist |
TTL and count-based purge limits. |
| Ordering | locationsOrderDirection |
Controls upload and retrieval order. |
| Templates | locationTemplate, geofenceTemplate |
Custom JSON structure for uploads. |
| Extras | extras |
Static key/value pairs merged into every record. |
| Persist mode | persistMode |
Which event types are written to SQLite. |
| Diagnostics | disableProviderChangeRecord |
Suppress provider-change records. |
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.maxDaysToPersist = 3
config.persistence.maxRecordsToPersist = 1000
config.persistence.extras = [
"user_id": 123,
"appVersion": "1.2.3"
]
config.persistence.persistMode = .all
}
Storage lifecycle¶
Records are written to SQLite immediately upon recording and deleted when any of the following occur:
- Your server returns a
20xresponse for the HTTP upload (see HttpConfig) - You call BGGeo.destroyLocations
maxDaysToPersistelapses (rolling TTL purge)maxRecordsToPersistwould be exceeded (oldest records are dropped)
Inspect the pending queue with BGGeo.getCount or BGGeo.getLocations.
Ordering¶
locationsOrderDirection controls the order in which records are selected
for upload or returned by BGGeo.getLocations:
"ASC"— oldest first (default)"DESC"— newest first
Templates¶
By default the SDK serializes locations and geofence events using its standard
JSON schema. Use locationTemplate and geofenceTemplate to
substitute a custom ERB template that reshapes the JSON to match your backend.
Use extras to merge static key/value metadata into every record at write
time, without a custom template.
Persist mode¶
persistMode controls which event types are written to SQLite. All events
are still delivered to their live callbacks (BGGeo.onLocation,
BGGeo.onGeofence) regardless of this setting. Events that
are not persisted are not eligible for HTTP uploads via HttpConfig.url.
The persist option on individual API calls can override this setting per-request:
let bgGeo = BGGeo.shared
Task {
do {
let location = try await bgGeo.getCurrentPosition(
samples: 3,
persist: true,
extras: ["get_current_position": true]
)
} catch {
print("[getCurrentPosition] error: \(error)")
}
}
Examples¶
Now grouped under PersistenceConfig¶
let bgGeo = BGGeo.shared
bgGeo.config.batchUpdate { config in
config.persistence.maxDaysToPersist = 14
config.persistence.maxRecordsToPersist = 5000
config.persistence.locationsOrderDirection = .ascending
config.persistence.locationTemplate = "{...}"
config.persistence.geofenceTemplate = "{...}"
config.persistence.persistMode = .all
config.persistence.extras = ["user_id": 123]
}
Configure persistence behavior¶
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.maxDaysToPersist = 14
config.persistence.maxRecordsToPersist = 5000
config.persistence.locationsOrderDirection = .ascending
config.persistence.persistMode = .all
config.persistence.extras = ["user_id": 123, "appVersion": "1.2.3"]
config.http.url = "https://example.com/locations"
config.http.autoSync = true
}
Inspect and purge the database¶
let bgGeo = BGGeo.shared
let pending = bgGeo.store.count
print("Pending records: \(pending)")
// Purge all records
bgGeo.store.destroyAll()
print("Destroyed all records")
Custom JSON templates¶
let bgGeo = BGGeo.shared
bgGeo.config.batchUpdate { config in
config.persistence.locationTemplate = """
{
"lat": <%= latitude %>,
"lng": <%= longitude %>,
"ts": "<%= timestamp %>"
}
"""
config.persistence.geofenceTemplate = """
{
"id": "<%= identifier %>",
"action": "<%= action %>",
"ts": "<%= timestamp %>"
}
"""
}
Members¶
extras¶
Optional arbitrary key/value pairs merged into each recorded location at write time.
These values are persisted and included in all HTTP uploads, making them
ideal for attaching static contextual metadata such as user_id, route_id,
or session_id.
See also
- HTTP Guide
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.http.url = "https://my-server.com/locations"
config.http.params = ["device_id": "abc123"]
config.persistence.extras = ["route_id": 1234]
}
The resulting HTTP request body:
POST /locations
{
"device_id": "abc123",
"location": {
"coords": {
"latitude": 45.51927004945047,
"longitude": -73.61650072045029
},
"extras": {
"route_id": 1234
}
}
}
geofenceTemplate¶
Optional custom ERB template for reshaping GeofenceEvent JSON in HTTP uploads.
Behaves like locationTemplate but includes two additional tags:
geofence.identifier and geofence.action. Use Ruby-style ERB tags to
interpolate field values:
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.geofenceTemplate = "{ \"lat\":<%= latitude %>, \"lng\":<%= longitude %>, \"geofence\":\"<%= geofence.identifier %>:<%= geofence.action %>\" }"
}
// Or a compact Array form:
bgGeo.config.batchUpdate { config in
config.persistence.geofenceTemplate = "[<%= latitude %>, <%= longitude %>, \"<%= geofence.identifier %>\", \"<%= geofence.action %>\"]"
}
Warning
The SDK does not automatically apply double-quotes around string data. Templates are JSON-encoded exactly as written.
Produces invalid JSON:
Template tags¶
Identical to locationTemplate with the following additions:
| Tag | Type | Description |
|---|---|---|
geofence.identifier |
String |
Identifier of the activated geofence |
geofence.action |
String |
"ENTER" or "EXIT" |
latitude |
Float |
|
longitude |
Float |
|
speed |
Float |
Meters |
heading |
Float |
Degrees |
accuracy |
Float |
Meters |
altitude |
Float |
Meters |
altitude_accuracy |
Float |
Meters |
timestamp |
String |
ISO-8601 |
uuid |
String |
Unique ID |
event |
String |
motionchange, geofence, heartbeat, providerchange |
odometer |
Float |
Meters |
activity.type |
String |
still, on_foot, running, on_bicycle, in_vehicle, unknown |
activity.confidence |
Integer |
0–100% |
battery.level |
Float |
0–100% |
battery.is_charging |
Boolean |
Whether device is plugged in |
mock |
Boolean |
True when location was generated from a mock app |
is_moving |
Boolean |
True if recorded while in moving state |
timestampMeta |
Object |
Timestamp metadata; see GeolocationConfig.enableTimestampMeta |
See also
- locationTemplate
- HttpConfig.rootProperty
- HTTP Guide
Incorrect¶
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.geofenceTemplate = "{\"timestamp\": <%= timestamp %>}"
}
Correct¶
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.geofenceTemplate = "{\"timestamp\": \"<%= timestamp %>\"}"
}
locationTemplate¶
Optional custom ERB template for reshaping LocationEvent JSON in HTTP uploads.
When set, the SDK evaluates the template string against each location record before serializing it. Use Ruby-style ERB tags to interpolate field values:
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.locationTemplate = "{\"lat\":<%= latitude %>,\"lng\":<%= longitude %>,\"event\":\"<%= event %>\",isMoving:<%= is_moving %>}"
}
// Or use a compact Array template:
bgGeo.config.batchUpdate { config in
config.persistence.locationTemplate = "[<%=latitude%>, <%=longitude%>, \"<%=event%>\", <%=is_moving%>]"
}
Warning
The SDK does not automatically insert quotes around string values. Templates are JSON-encoded exactly as written.
The following produces invalid JSON because timestamp is a string but is
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.locationTemplate = "{\"timestamp\": <%= timestamp %>}"
}
This renders invalid JSON:
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.persistence.locationTemplate = "{\"timestamp\": \"<%= timestamp %>\"}"
}
Configured extras¶
If extras are configured, the key/value pairs are merged directly
into the rendered location JSON.
let bgGeo = BGGeo.shared
bgGeo.ready { config in
config.http.url = "https://my.server.com/locations"
config.http.rootProperty = "data"
config.persistence.locationTemplate = "{\"lat\":<%= latitude %>,\"lng\":<%= longitude %>}"
config.persistence.extras = ["foo": "bar"]
}
Produces:
Template tags¶
| Tag | Type | Description |
|---|---|---|
latitude |
Float |
|
longitude |
Float |
|
speed |
Float |
Meters |
heading |
Float |
Degrees |
accuracy |
Float |
Meters |
altitude |
Float |
Meters |
altitude_accuracy |
Float |
Meters |
timestamp |
String |
ISO-8601 |
uuid |
String |
Unique ID |
event |
String |
motionchange, geofence, heartbeat, providerchange |
odometer |
Float |
Meters |
activity.type |
String |
still, on_foot, running, on_bicycle, in_vehicle, unknown |
activity.confidence |
Integer |
0–100% |
battery.level |
Float |
0–100% |
battery.is_charging |
Boolean |
Is device plugged in? |
mock |
Boolean |
True if generated by mock provider |
is_moving |
Boolean |
Device was moving when recorded |
timestampMeta |
Object |
Timestamp metadata; see GeolocationConfig.enableTimestampMeta |
See also
- HTTP Guide
- geofenceTemplate
- HttpConfig.rootProperty
locationsOrderDirection¶
public var locationsOrderDirection:LocationsOrderDirection
Sort order used when selecting records for upload or returning them from
BGGeo.getLocations. Defaults to "ASC" (oldest first).
"ASC"— oldest records first"DESC"— newest records first
maxDaysToPersist¶
Maximum number of days to retain a persisted record in the SDK's on-device
SQLite database. Defaults to 1 day.
When your server fails to return a 20x response, the SDK continues retrying
uploads. If a record remains unuploaded for longer than maxDaysToPersist days,
it is permanently discarded to prevent unbounded database growth.
maxRecordsToPersist¶
Maximum number of records the SDK may retain in its on-device SQLite database.
Defaults to -1 (no limit).
When a limit is set and the stored record count would exceed it, the oldest records are purged to make room for the newest.
See HttpEvent for details on upload behavior.
persistMode¶
public var persistMode:PersistMode
Controls which event types the SDK writes to its internal SQLite database. Defaults to PersistMode.All.
All recorded events are always delivered to their live callbacks (BGGeo.onLocation and BGGeo.onGeofence). This setting only determines what is written to persistent storage. Events that are not persisted are also not eligible for HTTP uploads via HttpConfig.url.
| Value | Description |
|---|---|
| PersistMode.All | Default — persist both location and geofence events. |
| PersistMode.Location | Persist location events only. |
| PersistMode.Geofence | Persist geofence events only. |
| PersistMode.None | Persist nothing. |
Warning
This setting is intended for specialized cases. For example, if you need
continuous location tracking via BGGeo.start but only
want to store geofence events, configure persistMode: PersistMode.Geofence.