# Flutter

## Prerequisites

1. Add [`terra_flutter_rt`](https://pub.dev/packages/terra_flutter_rt) to your `pubspec.yaml`:

```yaml
dependencies:
  terra_flutter_rt: ^X.X.X
```

2. **iOS:** In your `Info.plist`, add:
   * `Privacy - Bluetooth Always Usage Description`: Justification for BLE usage
   * `Privacy - Motion Usage Description`: Justification for motion sensor usage (required if streaming accelerometer, gyroscope, or step data from the phone's built-in sensors via `Connection.apple`)
3. **Android:** Permissions are requested automatically by the SDK on initialization.

## SDK Initialization

{% hint style="info" %}
Initialize the SDK every time the app is opened or brought into the foreground.
{% endhint %}

```dart
import 'package:terra_flutter_rt/terra_flutter_rt.dart';
import 'package:terra_flutter_rt/types.dart';

await TerraFlutterRt.init('YOUR_DEV_ID', 'YOUR_REFERENCE_ID');
```

## Initializing a Connection

Register the device with Terra using an authentication token generated **from your backend**:

```dart
final token = 'yourAuthToken'; // Generated from your backend

await TerraFlutterRt.initConnection(token);
```

To generate the **token**, make the below call **from your backend**:

{% openapi src="<https://raw.githubusercontent.com/tryterra/openapi/refs/heads/master/v5.yml>" path="/auth/generateAuthToken" method="post" %}
<https://raw.githubusercontent.com/tryterra/openapi/refs/heads/master/v5.yml>
{% endopenapi %}

## Device Scanning

Two approaches depending on your needs:

### Option 1: Built-in scan widget

On Android, this shows a native device picker. On iOS, use the `iOSScanView` widget.

```dart
import 'package:terra_flutter_rt/ios_controller.dart';

// Android: shows native picker
await TerraFlutterRt.startDeviceScan(
  Connection.ble,
  connectionCallback: (connected) {
    print('Device connected: $connected');
  },
);

// iOS: embed the native BLE scanner view in your widget tree
// (renders empty Container on Android)
iOSScanView()
```

### Option 2: Programmatic scan with callback

Discover devices one by one and connect manually:

```dart
await TerraFlutterRt.startDeviceScanToCallback(
  Connection.ble,
  (Device device) async {
    print('Found: ${device.deviceName}');
    // Connect to this device
    await TerraFlutterRt.connectDevice(device);
  },
  connectionCallback: (connected) {
    print('Connection status: $connected');
  },
);
```

## Real-Time Data Streaming

Once a device is connected, start streaming data to your app via a callback:

```dart
void onUpdate(Update data) {
  print('${data.type.datatypeString}: ${data.val}');
}

await TerraFlutterRt.startRealtimeToApp(
  Connection.ble,
  [DataType.heartRate, DataType.steps],
  onUpdate,
);
```

To stream to Terra's server instead, see [Your App → Terra](/streaming-api/your-app-greater-than-terra/flutter.md).

## Stop & Disconnect

```dart
await TerraFlutterRt.stopRealtime(Connection.ble);
await TerraFlutterRt.disconnect(Connection.ble);
```

## WatchOS Integration

To stream data from an Apple Watch:

```dart
// Connect to paired Apple Watch (iOS only — returns false on Android)
final connected = await TerraFlutterRt.connectWatchOS();

if (connected) {
  // Start receiving watch data
  await TerraFlutterRt.startRealtimeToApp(
    Connection.watchOs,
    [DataType.heartRate],
    onUpdate,
  );
}
```

{% hint style="info" %}
The watchOS app itself must be written in native Swift using the `Terra` class from the `TerraRTiOS` framework. See the [iOS WatchOS guide](/streaming-api/connect-wearable-to-sdk/ios-swift.md#watchos-integration) for the watch-side setup.
{% endhint %}

You can also control workout sessions on the watch from your Flutter app:

```dart
await TerraFlutterRt.resumeWatchOSWorkout();
await TerraFlutterRt.pauseWatchOSWorkout();
await TerraFlutterRt.stopWatchOSWorkout();
```


---

# 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.tryterra.co/streaming-api/connect-wearable-to-sdk/flutter.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.
