# Listeners/Callbacks

## SDK State Listener

Triggers whenever the [MoveSDKState](/move-platform/sdk/models/movestate.md) changes.

{% hint style="info" %}
Set an MOVE SDK State listener using`sdkStateListener`([Android](https://docs.movesdk.com/move-platform/sdk/models/pages/-MZIfp4AHvpUSOaycA60#DolphinSdk.Builderv1.1-sdkstatelistenerSdkstatelistener)/[iOS](/move-platform/sdk/api-interface/ios/services.md#set-sdk-state-listener)) API to anticipate handling the MOVE SDK State changes, start detection services when [MoveSDKState](/move-platform/sdk/models/movestate.md) is `.ready` or handle`.error` if occurred.
{% endhint %}

{% hint style="warning" %}
For android platform it is necessary to start listen explicitly by calling:

```typescript
if (Platform.OS === 'android') {
    MoveSdk.startNativeSdkStateListener();
}
```

{% endhint %}

{% tabs %}
{% tab title="Android" %}

```kotlin
interface StateListener {
    fun onStateChanged(sdk: MoveSdk, state: MoveSdkState)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveSDKStateCallback = (_ state: MoveSDKState) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addSdkStateListener(sdkStateChanged: (state: SdkState) => void): ListenerSubscription;
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Stream<MoveState>
```

{% endtab %}
{% endtabs %}

| **Parameter**                                          |                                                                |
| ------------------------------------------------------ | -------------------------------------------------------------- |
| [MoveSDKState](/move-platform/sdk/models/movestate.md) | Latest [MoveSDKState](/move-platform/sdk/models/movestate.md). |

## Auth State Update Listener

Triggers whenever the [MoveAuthState](/move-platform/sdk/models/moveauth.md) changes.

{% hint style="warning" %}

### Authentication Expiry

The host app is expected to monitor [MoveAuthState](/move-platform/sdk/models/moveauthstate.md) updates via `authStateUpdateListener` API and handle those changes accordingly.

Check [Authentication updates and expiry](/move-platform/sdk/models/moveauthstate.md#authentication-updates-and-expiry) for more details about authentication expiry and renewal.
{% endhint %}

{% tabs %}
{% tab title="Android" %}

```kotlin
interface AuthStateUpdateListener {
    fun onAuthStateUpdate(state: MoveAuthState)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveAuthStateCallback = (_ state: MoveAuthState) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addAuthStateListener(authStateChanged: (event: AuthStateEvent) => void): ListenerSubscription;
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart"><strong>Stream&#x3C;MoveAuthState>
</strong></code></pre>

{% endtab %}
{% endtabs %}

| **Parameter**                                               |                                                                     |
| ----------------------------------------------------------- | ------------------------------------------------------------------- |
| [MoveAuthState](/move-platform/sdk/models/moveauthstate.md) | Latest [MoveAuthState](/move-platform/sdk/models/moveauthstate.md). |

## Trip State Listener

Triggers whenever the [MoveTripState](/move-platform/sdk/models/movetripstate.md) changes.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface TripStateListener {
    fun onTripStateChanged(sdk: MoveSdk, tripState: MoveTripState)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveTripStateCallback = (_ tripState: MoveTripState) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addTripStateListener(tripStateChanged: (state: TripState) => void): ListenerSubscription;
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart"><strong>Stream&#x3C;MoveTripState>
</strong></code></pre>

{% endtab %}
{% endtabs %}

| **Parameter**                                               |                                                                     |
| ----------------------------------------------------------- | ------------------------------------------------------------------- |
| [MoveTripState](/move-platform/sdk/models/movetripstate.md) | Latest [MoveTripState](/move-platform/sdk/models/movetripstate.md). |

## Trip Start Listener

Triggers whenever a trip actually starts.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface TripStartListener {
    fun onTripStarted(startDate: Date)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveTripStartCallback = (_ startDate: Date) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
MoveSdk.addTripStartListener(tripStartTriggered: (start: Date) => void): ListenerSubscription;
```

{% endtab %}
{% endtabs %}

| **Parameter** |                                    |
| ------------- | ---------------------------------- |
| Date          | The actual start time of the trip. |

## Trip Metadata Provider

This triggers whenever a trip is ending, allowing the host app to append metadata along with that trip if needed.

{% hint style="info" %}
Trip Metadata is only available for car, cycling, train, tram, metro, and bus items. Metadata is also unavailable if public transport data is sourced from POIs.
{% endhint %}

{% tabs %}
{% tab title="Android" %}

```kotlin
interface TripMetadataProvider {
    fun provideMetadata(start: Long, end: Long): Map<String, String>
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveMetaDataCallback = (_ tripStart: Date, _ tripEnd: Date) -> [String: String]
```

{% endtab %}
{% endtabs %}

| **Parameter**     | **Type**    |                              |
| ----------------- | ----------- | ---------------------------- |
| start / tripStart | Long / Date | Trip start timestamp / date. |
| end / tripEnd     | Long / Date | Trip end timestamp / date.   |

| **Return**                                  |
| ------------------------------------------- |
| A String dictionary of the trip's metadata. |

## Device Status Callback

Triggers whenever [MoveDeviceStatus](/move-platform/sdk/models/movedevicestatus.md) changes. [MoveDeviceStatus](/move-platform/sdk/models/movedevicestatus.md) represents the current device's system permissions (for [Android](/move-platform/sdk/appendix/android/permission-handling.md) / [iOS](/move-platform/sdk/appendix/ios/permission-handling.md)) and services status.

{% tabs %}
{% tab title="iOS" %}

<pre class="language-swift"><code class="lang-swift"><strong>typealias MoveDeviceStatusCallback = (_ status: MoveDeviceStatus) -> Void
</strong></code></pre>

{% endtab %}
{% endtabs %}

| **Parameter**                                                     |                                                                           |
| ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
| [MoveDeviceStatus](/move-platform/sdk/models/movedevicestatus.md) | Latest [MoveDeviceStatus](/move-platform/sdk/models/movedevicestatus.md). |

## Service Failure Callback

Triggers whenever [MoveServiceFailures](/move-platform/sdk/models/moveservicefailure.md) change.

{% tabs %}
{% tab title="Android" %}

<pre class="language-kotlin"><code class="lang-kotlin">interface MoveErrorListener {
<strong>    fun onMoveError(serviceFailures: List&#x3C;MoveServiceFailure>)
</strong>}
</code></pre>

{% endtab %}

{% tab title="iOS" %}

```swift
public typealias MoveServiceFailureCallback = (_ permissions: [MoveServiceFailure]) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addErrorsListener(errorsReceived: (errors: ErrorListType) => void): ListenerSubscription;
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Stream<List<MoveServiceError>>
```

{% endtab %}
{% endtabs %}

| **Parameter**                                                         |                                                                                 |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [MoveServiceFailure](/move-platform/sdk/models/moveservicefailure.md) | List of [MoveServiceFailures](/move-platform/sdk/models/moveservicefailure.md). |

## Service Warning Callback

Triggers whenever [MoveServiceWarnings](/move-platform/sdk/models/moveservicewarning.md) change.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface MoveWarningListener {
    fun onMoveWarning(serviceWarnings: List<MoveServiceWarning>)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
public typealias MoveServiceWarningCallback = (_ permissions: [MoveServiceWarning]) -> Void
```

{% endtab %}

{% tab title="React Native" %}

<pre class="language-typescript"><code class="lang-typescript"><strong>static addWarningsListener(warningsReceived: (warnings: ErrorListType) => void): ListenerSubscription;
</strong></code></pre>

{% endtab %}

{% tab title="Flutter" %}

```dart
Stream<List<MoveServiceWarning>>
```

{% endtab %}
{% endtabs %}

| **Parameter**                                                         |                                                                                 |
| --------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [MoveServiceWarning](/move-platform/sdk/models/moveservicewarning.md) | List of [MoveServiceWarnings](/move-platform/sdk/models/moveservicewarning.md). |
|                                                                       |                                                                                 |

## Initialization Listener

Represents the potential errors occurring when updating the [MoveAuth](/move-platform/sdk/models/moveauth.md).

{% tabs %}
{% tab title="Android" %}

```kotlin
interface InitializeListener {
    fun onError(error: MoveConfigurationError)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
public typealias MoveInitializationCallback = (_ error: MoveConfigurationError) -> Void
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="130">Parameter</th><th width="216"></th><th></th></tr></thead><tbody><tr><td><strong>Parameter</strong></td><td><strong>Type</strong></td><td></td></tr><tr><td>error</td><td><a href="/pages/-MaaWYf8OHiAF4kfCW1V">MoveConfigurationError</a></td><td><p>An error to notify when the configuration could </p><p>not be loaded from the server.</p></td></tr></tbody></table>

## Log Callback

Triggers whenever a new log event occurs.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface MoveLogCallback {
    fun onLogReceived(eventName: String, value: String?)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveLogCallback = (_ log: String, _ value: String) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addLogListener(logReceived: (event: MoveSdkLog) => void): ListenerSubscription;

export type MoveSdkLog = {
  message: string;
  value?: string;
};
```

{% endtab %}
{% endtabs %}

| **Parameter** | **Type** |                     |
| ------------- | -------- | ------------------- |
| log           | String   | New log event.      |
| value         | String   | Log value. Optional |

The SDK will trigger log messages to improve debugging.

## Remote Config Change Listener

{% hint style="info" %}
Since MOVE SDK v2.5
{% endhint %}

Will be triggered when the [MoveConfig](/move-platform/sdk/models/moveconfig.md) was successfully fetched from the server via [updateConfig](/move-platform/sdk/api-interface/android/services.md#update-config) (Android) / [update](/move-platform/sdk/api-interface/ios/setup.md#update-config) (iOS).

If the MoveConfig object couldn't be fetched from the server then a [MoveConfigurationError](/move-platform/sdk/models/moveconfigurationerror.md) ServiceUnreachable will be triggered.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface RemoteConfigChangeListener {
    fun onConfigChanged(config: MoveConfig)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveRemoteConfigChangeCallback = (_ config: MoveConfig) -> Voidstatic addConfigChange(warningsReceived: (warnings: ErrorListType) => void): ListenerSubscription
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addRemoteConfigChangeListener(configChangeReceived: (config: Array<IssueListService>) => void): ListenerSubscription
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart"><strong>Stream&#x3C;MoveConfig>
</strong></code></pre>

{% endtab %}
{% endtabs %}

## Setup Authorization Callback

{% hint style="info" %}
Since MOVE SDK v2.9
{% endhint %}

Will return the success or failure of the internal MOVE SDK authentication process during [setup](/move-platform/sdk/api-interface/android/initialization.md#setup). (also see [MoveAuthResult](/move-platform/sdk/models/moveauthresult.md))

{% tabs %}
{% tab title="Android" %}

```kotlin
interface MoveAuthCallback {
    fun onResult(result: MoveAuthResult)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveAuthCallback = (_ result: MoveAuthResult) -> Void
```

{% endtab %}

{% tab title="React Native" %}

{% endtab %}

{% tab title="Flutter" %}

```dart
object : MoveSdk.MoveAuthCallback {
    override fun onResult(authResult: MoveAuthResult) {
        uiThreadHandler.post {
            ...
            when (authResult.status) {
                AuthSetupStatus.SUCCESS -> result.success("success")
                AuthSetupStatus.INVALID_CODE -> // e.g. result.error(...)
                AuthSetupStatus.NETWORK_ERROR -> // e.g. result.error(...)
            }
        }
    }
}
```

{% endtab %}
{% endtabs %}

## Device Discovery Listener

{% hint style="info" %}
Since MOVE SDK v2.4
{% endhint %}

Will be triggered during a [BDD - Device Discovery](/move-platform/move-services.md#bdd-device-discovery) scan.&#x20;

{% tabs %}
{% tab title="Android" %}

```kotlin
interface DeviceDiscoveryListener {
    fun onScanResult(results: List<MoveScanResult)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
typealias MoveDeviceDiscoveryCallback = (_ results: [MoveScanResult]) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addDeviceDiscoveryListener(onScanResult: (state: Array<MoveScanResult>) => void): ListenerSubscription
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Stream<List<MoveScanResult>>
```

{% endtab %}
{% endtabs %}

| **Parameter** |                                                                         |
| ------------- | ----------------------------------------------------------------------- |
| results       | List of [MoveScanResult](/move-platform/sdk/models/movescanresult.md)'s |

## MoveDevice State Listener / Callback

{% hint style="info" %}
Since MOVE SDK v2.10.0
{% endhint %}

Will be triggered when the status of a registered [MoveDevice](/move-platform/sdk/models/movedevice.md) changes. This [MoveDevice](/move-platform/sdk/models/movedevice.md) must be previously registered. See chapters "Register Device" ([Android](/move-platform/sdk/api-interface/android/services.md#register-device), [iOS](/move-platform/sdk/api-interface/ios/services.md#register-device))

{% tabs %}
{% tab title="Android" %}

```kotlin
interface MoveDeviceStateListener {
    fun onStateChanged(device: MoveDevice)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
public typealias MoveDeviceStateCallback = (_ results: [MoveDevice]) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addDeviceStateListener(onScanResult: (results: Array<MoveSdkDevice>) => void): ListenerSubscription
```

{% endtab %}

{% tab title="Flutter" %}

```dart
Stream<List<MoveDevice>>
```

{% endtab %}
{% endtabs %}

## SDK Health Listener / Callback

{% hint style="info" %}
Since MOVE SDK v2.11.0
{% endhint %}

Will be triggered when the health score of the MOVE SDK changes. A [MoveHealthItem](/move-platform/sdk/models/movehealthitem.md) (iOS, React Native) / [MoveHealthScore](/move-platform/sdk/models/movehealthscore.md) (Android) with the current data is provided.

{% tabs %}
{% tab title="Android" %}

```kotlin
interface MoveHealthScoreListener {
    fun onMoveHealthScoreChanged(score: MoveHealthScore)
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
public typealias MoveHealthScoreCallback = (_ result: [MoveHealthItem]) -> Void
```

{% endtab %}

{% tab title="React Native" %}

```typescript
static addHealthListener(scoreReceived: (health: MoveHealthScore) => void): ListenerSubscription
```

{% endtab %}

{% tab title="Flutter" %}

<pre class="language-dart"><code class="lang-dart"><strong>Stream&#x3C;List&#x3C;MoveHealthItem>>
</strong></code></pre>

{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.movesdk.com/move-platform/sdk/models/listeners-callbacks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
