# Listeners/Callbacks

## SDK State Listener

Triggers whenever the [MoveSDKState](https://docs.movesdk.com/move-platform/sdk/models/movestate) changes.

{% hint style="info" %}
Set an MOVE SDK State listener using`sdkStateListener`([Android](https://docs.movesdk.com/move-platform/api-interface/android/initialization#DolphinSdk.Builderv1.1-sdkstatelistenerSdkstatelistener)/[iOS](https://docs.movesdk.com/move-platform/api-interface/ios/services#set-sdk-state-listener)) API to anticipate handling the MOVE SDK State changes, start detection services when [MoveSDKState](https://docs.movesdk.com/move-platform/sdk/models/movestate) 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](https://docs.movesdk.com/move-platform/sdk/models/movestate) | Latest [MoveSDKState](https://docs.movesdk.com/move-platform/sdk/models/movestate). |

## Auth State Update Listener

Triggers whenever the [MoveAuthState](https://docs.movesdk.com/move-platform/sdk/models/moveauth) changes.

{% hint style="warning" %}

### Authentication Expiry

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

Check [Authentication updates and expiry](https://docs.movesdk.com/move-platform/sdk/moveauthstate#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](https://docs.movesdk.com/move-platform/sdk/models/moveauthstate) | Latest [MoveAuthState](https://docs.movesdk.com/move-platform/sdk/models/moveauthstate). |

## Trip State Listener

Triggers whenever the [MoveTripState](https://docs.movesdk.com/move-platform/sdk/models/movetripstate) 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](https://docs.movesdk.com/move-platform/sdk/models/movetripstate) | Latest [MoveTripState](https://docs.movesdk.com/move-platform/sdk/models/movetripstate). |

## 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](https://docs.movesdk.com/move-platform/sdk/models/movedevicestatus) changes. [MoveDeviceStatus](https://docs.movesdk.com/move-platform/sdk/models/movedevicestatus) represents the current device's system permissions (for [Android](https://docs.movesdk.com/move-platform/sdk/appendix/android/permission-handling) / [iOS](https://docs.movesdk.com/move-platform/sdk/appendix/ios/permission-handling)) 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](https://docs.movesdk.com/move-platform/sdk/models/movedevicestatus) | Latest [MoveDeviceStatus](https://docs.movesdk.com/move-platform/sdk/models/movedevicestatus). |

## Service Failure Callback

Triggers whenever [MoveServiceFailures](https://docs.movesdk.com/move-platform/sdk/models/moveservicefailure) 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](https://docs.movesdk.com/move-platform/sdk/models/moveservicefailure) | List of [MoveServiceFailures](https://docs.movesdk.com/move-platform/sdk/models/moveservicefailure). |

## Service Warning Callback

Triggers whenever [MoveServiceWarnings](https://docs.movesdk.com/move-platform/sdk/models/moveservicewarning) 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](https://docs.movesdk.com/move-platform/sdk/models/moveservicewarning) | List of [MoveServiceWarnings](https://docs.movesdk.com/move-platform/sdk/models/moveservicewarning). |
|                                                                                            |                                                                                                      |

## Initialization Listener

Represents the potential errors occurring when updating the [MoveAuth](https://docs.movesdk.com/move-platform/sdk/models/moveauth).

{% 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="moveconfigurationerror">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](https://docs.movesdk.com/move-platform/sdk/models/moveconfig) was successfully fetched from the server via [updateConfig](https://docs.movesdk.com/move-platform/api-interface/android/services#update-config) (Android) / [update](https://docs.movesdk.com/move-platform/api-interface/ios/setup#update-config) (iOS).

If the MoveConfig object couldn't be fetched from the server then a [MoveConfigurationError](https://docs.movesdk.com/move-platform/sdk/models/moveconfigurationerror) 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](https://docs.movesdk.com/move-platform/api-interface/android/initialization#setup). (also see [MoveAuthResult](https://docs.movesdk.com/move-platform/sdk/models/moveauthresult))

{% 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](https://docs.movesdk.com/move-platform/move-services#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](https://docs.movesdk.com/move-platform/sdk/models/movescanresult)'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](https://docs.movesdk.com/move-platform/sdk/models/movedevice) changes. This [MoveDevice](https://docs.movesdk.com/move-platform/sdk/models/movedevice) must be previously registered. See chapters "Register Device" ([Android](https://docs.movesdk.com/move-platform/api-interface/android/services#register-device), [iOS](https://docs.movesdk.com/move-platform/api-interface/ios/services#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](https://docs.movesdk.com/move-platform/sdk/models/movehealthitem) (iOS, React Native) / [MoveHealthScore](https://docs.movesdk.com/move-platform/sdk/models/movehealthscore) (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 %}
