# Automatic Wedge Association

### **Configure AWA:**

The ability to enable or disable AWA is controlled via the `shouldEnableAWA` parameter in the IMSDeviceManager.configure method:

Example

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

```swift
// Configure AWA
IMSDeviceManager.configure(providers: [IMSDeviceProvidable], shouldEnableAWA: Bool = false)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Configure AWA
DsDeviceManager.initialize(application = context.applicationContext, providersList = providers, shouldEnableAWA = true)
```

{% endtab %}
{% endtabs %}

Both platforms use the `shouldEnableAWA` parameter in configure methods:

* When `true`: Changes are synchronized with the remote server immediately
* When `false`: Changes are only applied locally, without server communication

This flag provides flexibility for different usage scenarios:

1. Offline operations that will sync later
2. Batching multiple changes for efficiency
3. Handling poor connectivity conditions

### **Fetching missing vehicles API**

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

```swift
// IMSDeviceManager
func fetchMissingVehicles(completion: @escaping (Result<(wedges: [Wedge], missingVehicles: [Vehicle])>))
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
suspend fun fetchMissingVehicle(context: Context): Result<Pair<List<Wedge>, List<Vehicle>>>
```

{% endtab %}
{% endtabs %}

#### Purpose

\
This method allows client applications on both Android and iOS platforms to:

1. Retrieve the current set of registered wedge devices from the server
2. Retrieve the available vehicles from the server
3. Identify vehicles that do not have any associated wedge devices

### Parameters

#### Android

* `context: Context` - The Android application context

#### iOS

* Completion handler version: `completion` - A callback to handle the result

### Return Value

Both platform implementations return similar data:

* On success: Two lists<
  * List of Wedges - These are Wedges that have already been associated to a vehicle, which also contain the associated vehicleId
  * List of Vehicles - These are vehicles that do not have a wedge association
* On failure: An error describing what went wrong

#### Android

* `Result<Pair<List<Wedge>, List<Vehicle>>>`

#### iOS

* Completion handler: `Result<(wedges: [Wedge], missingVehicles: [Vehicle])>`

### Usage Example

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

```swift
// Fetch missing vehicles and process results
IMSDeviceManager.fetchMissingVehicles { result in
    switch result {
    case .success(let data):
        let (wedges, missingVehicles) = data
        
        // Use wedge information
        wedges.forEach { wedge in
            // Process each wedge
            print("Wedge: \(wedge.name), ID: \(wedge.deviceId)")
        }
        
        // Handle unassociated vehicles
        missingVehicles.forEach { vehicle in
            // Process each vehicle without an associated wedge
            print("Missing vehicle: \(vehicle.name), ID: \(vehicle.vehicleId)")
        }
        
    case .failure(let error):
        // Handle the error case
        print("Error fetching missing vehicles: \(error.localizedDescription)")
    }
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Fetch missing vehicles and process results
lifecycleScope.launch {
    val result = DsDeviceManager.fetchMissingVehicle(context)
    
    result.onSuccess { pair ->
        val (wedges, missingVehicles) = pair
        
        // Use wedge information
        wedges.forEach { wedge ->
            // Process each wedge
        }
        
        // Handle unassociated vehicles
        missingVehicles.forEach { vehicle ->
            // Process each vehicle without an associated wedge
        }
    }
    
    result.onFailure { error ->
        // Handle the error case
    }
}
```

{% endtab %}
{% endtabs %}

### Error Handling

The API can return failures in the following scenarios:

* Network connectivity issues
* Authorization or authentication failures
* Server-side errors
* Invalid or unexpected data formats

#### Android

Handle errors through the `Result.onFailure` callback or by catching exceptions.

#### iOS

Handle errors through the `Result.failure` case in the completion handler.

1. **Call within a coroutine**: This is a suspending function that should be called from within a coroutine scope
2. **Error handling**: Always handle potential failures in the Result object
3. **UI updates**: Since this involves network operations, don't call directly from the UI thread
4. **Rate limiting**: Avoid calling this method excessively to conserve network and battery resources

### Related APIs

Both platforms provide similar device management APIs:

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

```swift
// Get locally stored devices
IMSDeviceManager.associatedDevices -> Set<IMSDevice>

// Associate a device
IMSDeviceManager.associateDevice(
    _ device: IMSDevice, 
    completion: @escaping (Result<Void>)
)

// Unassociate a device
IMSDeviceManager.disassociateDevice(
    _ device: IMSDevice, 
    completion: @escaping (Result<Void>)
)
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
// Get locally stored devices
DsDeviceManager.getAssociatedDevices(): List<DsDevice>

// Associate a device
DsDeviceManager.associateDevice(
    context: Context, 
    device: DsDevice,
): DsResult

// Unassociate a device
DsDeviceManager.unAssociateDevice(
    context: Context, 
    device: DsDevice,
): DsResult
```

{% endtab %}
{% endtabs %}

### Thread Safety

* **Android**: The API is thread-safe and uses coroutines with appropriate dispatchers
* **iOS**: The API is thread-safe and uses GCD (Grand Central Dispatch) to manage background operations

### Platform-Specific Requirements

#### Android

* Minimum SDK version: 21 (Android 5.0)
* Permissions: `INTERNET`, `ACCESS_NETWORK_STATE`
* Kotlin Coroutines library

#### iOS

* Minimum iOS version: 13.0 (iOS 15.0+ for async/await)
* No special permissions required

### Best Practices

1. **Connection Handling**: Check for network connectivity before calling
2. **Error Handling**: Always implement proper error handling
3. **UI Updates**: All returned data should be used to update UI on the main thread

### Limitations (iOS Only)

* **Initial Connection Requirement:** Secondary users must maintain an active device screen when first accessing wedges previously associated by primary users through Automatic Wedge Association.
* **Trip Capture**: After successful initial pairing, trip capture operates normally without screen wake requirements.
* **Impact**: Connection attempts fail when the device screen remains locked during initial association, though the system continues retry attempts at each trip initiation.
* **Workaround**: Ensure device screens remain unlocked when secondary users initially access primary user-associated wedges via Automatic Wedge Association.
* **Technical Impact**: This constraint affects user handoff mechanisms in multi-user environments where wedges are shared through the Automatic Wedge Association feature.

<br>
