Skip to main content

Permissions Runtime Behavior

1. Overview​

This document explains how the Telematics SDK monitors permission state changes at runtime and how it reacts to telemetry interruptions on iOS.

It describes the limitations imposed by the operating system, the internal state model used by the SDK, and the callback mechanisms exposed to notify the application of relevant events.


2. Detects permission changes only in the foreground​

On iOS, an app that moves to the background can remain active or be suspended, depending on whether there is a service that justifies its execution in the background. As long as there is a valid service, such as active location updates, the app remains in an active state in the background, allowing timers and callbacks to run.

When there is no longer a valid background service, the system suspends the app. A suspended app:

  • does not execute code
  • does not receive callbacks
  • cannot react to permission changes

Permission changes are always initiated by the user outside the context of the application, typically in the system settings. iOS does not provide global callbacks or background notifications to inform a suspended application that a permission has been removed or reset. As a result, if the application is suspended at the time of the change, that change will only be observable when the application resumes running.

In practice, this means that:

  • Detection of permission changes is only guaranteed when the application returns to the foreground
  • Background verification is inherently unreliable
  • There is no reliable way to react to a permission reset while the application remains in the background

For this reason, the Telematics SDK checks the permissions state whenever the application enters the foreground. This is the only time when the system guarantees that the application is active and able to execute code, allowing the SDK to consistently detect changes and notify the application in order to react appropriately.


3. How it works in practice​

The Telematics SDK reevaluates the status of permissions as soon as the application becomes active again. This point in the lifecycle, associated with applicationDidBecomeActive, is the first moment guaranteed by the system when the SDK can execute code and validate the actual status of permissions.

Whenever the application becomes active, the SDK performs a deterministic evaluation of:

  • current permissions
  • previously persisted telemetry state
  • actual runtime telemetry state
  • time since the last collected sample

This evaluation can result in:

  1. A callback to the application, notifying it of a relevant event
  2. A reconciliation action, where the SDK automatically aligns runtime telemetry with its intended state

These two outcomes are independent: a reconciliation may happen with or without a callback.

3.1 Internal state vs current runtime state​

The SDK distinguishes between two fundamental concepts:

Internal telemetry state​

  • Represents whether telemetry is intended to be active
  • Is persisted across app launches
  • Is only changed when the application explicitly starts or stops telemetry
  • Reflects user intent

Current runtime state​

  • Represents whether telemetry sensors are currently running in the process
  • Can change implicitly due to:
    • permission removal
    • app suspension or termination
    • system intervention (e.g. SIGKILL)

When these two states diverge, the SDK may attempt to reconcile the runtime state to match the internal state when the app becomes active.

Reconciliation never modifies the internal state.

It only starts or stops runtime telemetry to restore consistency.

In some interruption scenarios, runtime telemetry may stop before collected samples are sent to the server. The SDK includes a recovery mechanism to flush pending data once execution resumes.

3.2 Callbacks exposed by the SDK​

The SDK exposes three distinct callbacks, each corresponding to a specific class of events.

Callback 1 — Permissions missing​

The application is notified when:

  • one or more mandatory permissions are missing
  • telemetry is not expected to be running according to the internal state

This callback informs the application that telemetry cannot be started until the missing permissions are restored.


Callback 2 — Permissions lost while running​

The application is notified when:

  • mandatory permissions are missing
  • telemetry was expected to be active

The SDK reports the moment from which telemetry is no longer valid and the list of missing permissions, allowing the application to reason about data gaps and take corrective action.

In this case, the SDK also stops runtime telemetry to prevent inconsistent data collection.


Callback 3 — Telemetry gap detected​

The application is notified when:

  • telemetry was expected to be active
  • permissions are currently valid
  • there was a significant interruption in sample collection

The SDK reports:

  • when telemetry was interrupted
  • when it resumed

This callback may be triggered in scenarios such as:

  • the application being terminated while telemetry was active
  • permissions being temporarily removed and restored before the app returns to the foreground
  • the device being restarted while telemetry was active

This callback is used to signal incomplete or interrupted trips, even if telemetry has already restarted automatically.

3.3 Interruption threshold​

The SDK applies a fixed time threshold to distinguish between:

  • short, insignificant interruptions
  • meaningful breaks in telemetry collection

If the interruption duration is below the threshold, the SDK resumes telemetry silently.

If the interruption exceeds the threshold, the SDK reports a telemetry gap to the application using the 3rd Callback - Telemetry gap detected.

This mechanism prevents unnecessary notifications while still guaranteeing visibility into relevant data loss.

3.4 Reconciliation behavior​

During foreground evaluation, the SDK may:

  • start telemetry if it should be running but is not
  • stop telemetry if it should not be running but is

This process:

  • does not modify the internal telemetry state
  • does not necessarily trigger a callback
  • exists to restore consistency between intent and runtime execution

4. Pending data recovery after process interruption​

In some scenarios, telemetry may be interrupted by the system before collected samples are sent to the server.

This can occur when:

  • the application is terminated while telemetry is active
  • a mandatory permission is revoked, causing a system-level termination
  • the process is killed by the system (e.g. SIGKILL)
  • the device is restarted while telemetry is active

In these cases, telemetry samples, vehicle positions and attention events may remain stored locally but not yet uploaded, since data transmission is asynchronous and cannot be guaranteed before termination.

4.1 Automatic pending data flush​

To handle this, the SDK includes a recovery mechanism that attempts to flush pending data as soon as execution resumes.

The SDK automatically tries to send pending data when initSDK completes successfully and the SDK is authenticated.

This mechanism:

  • recovers data left unsent due to crashes or forced termination
  • does not require the user to restart telemetry
  • does not alter the internal telemetry state

If the SDK is not authenticated (for example, after the session was invalidated), the flush is skipped and retried automatically after the next successful initSDK with new tokens.


Important notes​

  • Background Modes are not permissions: they are application capabilities that must be correctly configured.
  • Motion does not keep the background active: it only complements data collection.
  • Location (Always) is the determining factor for continuous background execution.
  • Permission changes are not detected in background: the SDK does not guarantee immediate detection of permission removal or restoration if the application is suspended. Permission changes are only reliably evaluated when the application becomes active again.

5. Usage Example​

The Telematics SDK exposes three callbacks that allow the application to react to permission changes and telemetry interruptions.

Callback 1 — Permissions missing​

Triggered when the SDK evaluates the current permission state and detects whether mandatory permissions are missing or restored, while telemetry is not expected to be running.

This callback is used both to signal missing permissions and to signal that the permission state has become consistent again.

Typical use cases:

  • block or unblock UI
  • prompt the user to grant permissions
  • react to permissions being restored
  • prevent telemetry from starting while permissions are missing
sdk.onPermissionsMissing = { [weak self] (missingPermissions: [String]) in
DispatchQueue.main.async {

if missingPermissions.isEmpty {
// Permissions are now consistent with SDK requirements
} else {
// One or more mandatory permissions are missing
}
}
}

Important note: An empty array ([]) explicitly indicates that all mandatory permissions are now granted, and that the application state is once again aligned with the SDK requirements.


Callback 2 — Permissions lost while running​

Triggered when mandatory permissions are removed while telemetry was expected to be active.

In this scenario:

  • the SDK automatically stops runtime telemetry
  • the internal telemetry state remains unchanged (still marked as active)
  • the application is informed of when telemetry became invalid

Typical use cases:

  • notify the user that telemetry was interrupted
  • explicitly stop the telemetry to change the internal state
  • request permission authorization again
sdk.onPermissionsLostWhileRunning = { [weak self] (lostAt: Date, missingPermissions: [String]) in
DispatchQueue.main.async {

// Telemetry was interrupted due to permission removal

// lostAt indicates when telemetry became invalid
// missingPermissions contains the permissions that were removed
}
}

Callback 3 — Telemetry gap detected​

Triggered when telemetry was expected to be active, permissions are currently valid, and a significant interruption in sample collection was detected.

This callback may occur even if telemetry has already restarted automatically.

Typical use cases:

  • be informed about gaps in the data
sdk.onTelemetryGapDetected = { [weak self] (from: Date, to: Date) in
DispatchQueue.main.async {

// A telemetry interruption was detected
// • from: moment telemetry stopped producing samples
// • to: moment telemetry resumed

// Telemetry should be already running again at this point
}
}