> For the complete documentation index, see [llms.txt](https://docs.hackle.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hackle.io/en/development-guide/flutter.md).

# Flutter

{% hint style="info" %}
Hackle Flutter SDK supports Flutter SDK 2.0.0 and above.

Flutter SDK is built on top of [Android SDK](/en/development-guide/android.md) and [iOS SDK](/en/development-guide/ios.md). The following OS versions are supported.

* Android API 21 (5.0 LOLLIPOP) and above
* iOS 13 and above
  {% endhint %}

<details>

<summary>OS Support by Flutter SDK Version</summary>

<table><thead><tr><th width="244.765625">Hackle Flutter SDK Version</th><th>Supported OS</th></tr></thead><tbody><tr><td>Below 2.29.0</td><td><ul><li>Android API 16 and above</li><li>iOS 10 and above</li></ul></td></tr><tr><td>2.29.0 and above, below 2.32.0</td><td><ul><li>Android API 16 and above</li><li>iOS 13 and above</li></ul></td></tr><tr><td>2.32.0 and above</td><td><ul><li>Android API 21 and above</li><li>iOS 13 and above</li></ul></td></tr></tbody></table>

</details>

## Add SDK Dependency

[![](https://img.shields.io/pub/v/hackle)](https://pub.dev/packages/hackle)

Add the SDK dependency.

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

```bash
flutter pub add hackle
```

{% endtab %}

{% tab title="pubspec.yaml" %}

```yaml
dependencies:
	hackle: ^2.7.0
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
After installing or updating the SDK, you must rebuild the app for the integration changes to take effect.
{% endhint %}

## SDK Initialization

You must initialize `HackleApp` before using the SDK. An SDK Key is required to initialize `HackleApp`.

* `HackleApp` is a class that provides methods for using the SDK features.
* You can find the SDK Key in [SDK Integration Info](https://dashboard.hackle.io/config/sdk-setting) on the Hackle Service Dashboard.

During initialization, the SDK fetches required information from the Hackle server and stores it locally.

Initialization runs asynchronously, and you can use `await` to wait until initialization is complete.

{% hint style="warning" %}
If you call A/B Test or Feature Flag methods before initialization completes, they will return the default group (A) or off (false).
{% endhint %}

```dart
import "package:hackle/hackle.dart";

await HackleApp.initialize(YOUR_APP_SDK_KEY);
```

#### Recommended Initialization Strategy: Initialize via Splash Screen

Instead of launching the app immediately, display a splash screen while the SDK initializes. Once initialization completes, use a callback to close the splash screen and allow users to interact with the app.

### Inject User on Initialization

You can initialize the SDK with user information included.

* If no user information is provided, the SDK uses user information stored in local storage.
* If user information is provided, the SDK does not use information stored in local storage.
* If no user is injected and no user information is stored in local storage, the SDK uses a user with the Hackle Device ID as the device ID.

{% hint style="info" %}
User information can be freely updated after SDK initialization using the user info setter functions.
{% endhint %}

{% hint style="warning" %}
User information injected during initialization is not merged with user information stored in local storage.

ex) If userId: A is stored in storage and you inject deviceId: B during initialization, the user will be set to userId: null, deviceId: B.
{% endhint %}

```dart
import "package:hackle/hackle.dart";

HackleConfig config = HackleConfigBuilder()
  .build();

HackleUser user = HackleUserBuilder()
  .userId("YOUR_USER_ID")
  .build();

await HackleApp.initialize(YOUT_APP_SDK_KEY, hackleConfig: config, user: user);
```

### SDK Initialization Config

You can add several configuration options when initializing the SDK.

```dart
import "package:hackle/hackle.dart";

HackleConfig config = HackleConfigBuilder()
  .build();

await HackleApp.initialize(YOUT_APP_SDK_KEY, hackleConfig: config);
```

<table data-full-width="false"><thead><tr><th width="223.26171875">Config</th><th width="295.48828125">Description</th><th width="125.8125">Default</th><th width="99.55859375">Supported Version</th></tr></thead><tbody><tr><td><code>exposureEventDedupIntervalMillis</code></td><td><p>Removes duplicate exposure events for the same A/B Test or Feature Flag distribution result triggered consecutively by the same user.</p><ul><li>Min value: 1000 (1 second)</li><li>Max value: 3600000 (1 hour)</li></ul></td><td>-1 (no deduplication)</td><td>All versions</td></tr><tr><td><code>debug</code></td><td>Outputs logs for all features to the console and sends events immediately.</td><td><code>false</code></td><td>2.1.0+</td></tr><tr><td><code>pollingIntervalMillis</code></td><td><p>Periodically updates settings configured in the Dashboard.</p><ul><li>Min value: 60000 (60 seconds)</li></ul></td><td>-1 (no periodic update)</td><td>2.3.0+</td></tr><tr><td><code>automaticScreenTracking</code></td><td>Detects Activity / ViewController changes at the Android / iOS level to track screen transitions.</td><td><code>true</code></td><td>2.21.0+</td></tr><tr><td><code>sessionPolicy</code></td><td>Configures session persistence and expiry conditions.</td><td><p><code>ALWAYS_NEW_SESSION</code> ,</p><p><code>1800000</code></p></td><td>2.30.0+</td></tr><tr><td><code>optOutTracking</code></td><td>Whether Opt-out is enabled.</td><td><code>false</code></td><td>2.30.0+</td></tr><tr><td><code>sessionTimeoutMillis</code> (deprecated)</td><td>Sets the session timeout duration. Please use <code>sessionPolicy</code> instead.</td><td>1800000 (30 minutes)</td><td>2.9.0+</td></tr></tbody></table>

#### Session Policy Configuration

You can control session persistence and expiry conditions by configuring the session policy.

```dart
import "package:hackle/hackle.dart";

HackleSessionPolicy sessionPolicy = HackleSessionPolicy.builder()
    .persistCondition(HackleSessionPersistCondition.nullToUserId)
    .timeoutCondition(
        HackleSessionTimeoutCondition.builder()
            .timeoutMillis(3600000)
            .onForeground(false)
            .onBackground(true)
            .onApplicationStateChange(true)
            .build()
    )
    .build();

HackleConfig config = HackleConfigBuilder()
    .sessionPolicy(sessionPolicy)
    .build();

await HackleApp.initialize(YOUR_APP_SDK_KEY, hackleConfig: config);
```

### Refresh Dashboard Config

You can explicitly refresh the Dashboard configuration.

{% hint style="warning" %}
This function can be called at most once every 60 seconds.
{% endhint %}

```dart
HackleApp.fetch();
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://docs.hackle.io/en/development-guide/flutter.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
