# Flutter SDK 3.0

> What changes when you move the Grovs Flutter plugin from 1.x to 3.0.

Source: https://docs.grovs.io/docs/upgrade-guides/flutter-3-0

3.0.0 of `grovs_flutter_plugin` keeps every Dart method, stream and type from 1.1.0 with the same signature. The only signature change: `GenerateLinkParams` gained two optional named parameters, `copyToClipboardIos` and `copyToClipboardAndroid`. Native config keys in `Info.plist` and `AndroidManifest.xml` keep their names.

What changes is underneath. The plugin pins the native 3.0 SDKs (`Grovs ~> 3.0` on iOS, `io.grovs:Grovs:3.0.0` on Android). So clipboard-assisted deferred deep linking runs on first launch, consent can be gated from the config files, and analytics is available. Most apps bump the version and decide how to gate on consent.

Requirements are unchanged from 1.1.0: **Flutter 3.3.0**, **Dart 3.9.2**, **Android 7.0 (API 24)**. iOS 13.0 is the minimum for 3.0.0.

> **Note:** There is no 2.x. The plugin goes from 1.1.0 to 3.0.0 to share a major version with the native SDKs it wraps.

## Checklist

1. [Bump the dependency](#1-bump-the-version) to 3.0.0 and refresh the native pods.
2. [Review your consent gating](#2-review-your-consent-gating) if you have a consent flow: start disabled through `GrovsEnabled` / `grovs_enabled` and call the new `setSDK(true)`.
3. [Decide on screen tracking](#3-decide-on-screen-tracking). Nothing is tracked until you add `Grovs.navigatorObserver`.
4. [Check the other behavior changes](#4-check-the-other-behavior-changes): the clipboard read, `startDate` on custom purchases, and your store privacy declarations.

## 1. Bump the version

In `pubspec.yaml`:

```yaml
dependencies:
  grovs_flutter_plugin: ^3.0.0
```

Then run `flutter pub get`. On iOS the podspec now requires `Grovs ~> 3.0` instead of `~> 2.3`. If CocoaPods can't find a matching version, refresh the specs:

```bash
cd ios && pod install --repo-update
```

On Android the plugin pulls in `io.grovs:Grovs:3.0.0` instead of `1.1.1`, with no change on your side.

## 2. Review your consent gating

**`setSDK` is new.** 1.x had no way to stop collection from Dart. In 3.0, `setSDK(false)` stops everything the native SDK does: no authentication, device lookup, clipboard read, events, screen views, or purchases. The plugin also drops deep links while disabled. `setSDK(true)` starts collection again and replays the link that launched the app while disabled.

**Start disabled through the config files.** The plugin configures the native SDK at launch, before `main()` runs, so calling `setSDK(false)` from Dart cannot prevent that first round of startup work. If you gate on consent, add the key and enable after consent:

```xml
<!-- Info.plist -->
<key>GrovsEnabled</key>
<false/>
```

```xml
<!-- AndroidManifest.xml, inside <application> -->
<meta-data
    android:name="grovs_enabled"
    android:value="false" />
```

```dart
// 3.0: on every launch, after restoring the stored decision
if (await ConsentStore.hasConsent()) {
  await Grovs().setSDK(true);
}
```

The value is not persisted, so store it yourself and call `setSDK(true)` on every launch where consent exists. See [Privacy & Consent](https://docs.grovs.io/docs/sdk/flutter/privacy).

## 3. Decide on screen tracking

The native 3.0 SDKs track screens automatically by default, but the plugin turns that off on both platforms so the Flutter host view is not reported and Flutter routes are not double-counted. An app that only bumps the version therefore sends no screen views, the same as on 1.x.

To start tracking Flutter routes, add the observer:

```dart
MaterialApp(
  navigatorObservers: [Grovs.navigatorObserver],
  // ...
);
```

Screen names come from `RouteSettings.name`; unnamed routes fall back to the route's runtime type, which is obfuscated in release builds. See [Events & Screen Tracking](https://docs.grovs.io/docs/sdk/flutter/analytics#automatic-screen-tracking) for what is tracked, how names are chosen, and how to alias them.

## 4. Check the other behavior changes

**Clipboard-assisted deferred deep linking is on.** On the first launch after install, the native SDK may read the clipboard to attribute the install to a copy-to-clipboard link, and iOS may show its system paste notice. This only happens when the backend reports recent clicks on copy-to-clipboard links for your project and the clipboard holds a web URL. If you never enable copy-to-clipboard for your project or its links, the clipboard is never read. Starting the SDK disabled prevents it too. See [Clipboard-assisted deferred deep linking](https://docs.grovs.io/docs/sdk/flutter/deep-linking#clipboard-assisted-deferred-deep-linking).

**`startDate` on `logCustomPurchase` is now forwarded.** In 1.x the value was ignored and the native SDK used the current time. In 3.0 it is sent as milliseconds since the epoch and honored on both platforms, so a purchase you back-date now carries the date you pass.

**Android configures once per process.** The native SDK is configured when the first Flutter engine attaches and not again for later engines. Consent state is shared by all engines.

**iOS drops an in-flight lookup on disable.** A deep link lookup that was in progress when `setSDK(false)` was called is dropped by the plugin. If consent is granted again before it completes, the native SDK may still deliver it.

**Update your store privacy declarations.** Screen views and custom events are new categories of collection once you use them. Check your App Privacy answers and Data safety form against [what the SDK collects](https://docs.grovs.io/docs/sdk/flutter/privacy#what-the-sdk-collects).

## What's new in 3.0

Nothing here is required.

- **[Consent gating](https://docs.grovs.io/docs/sdk/flutter/privacy)**: the `GrovsEnabled` / `grovs_enabled` config keys and `setSDK(bool)`.
- **[Custom events and screen tracking](https://docs.grovs.io/docs/sdk/flutter/analytics)**: `track`, `trackScreenView`, `setGlobalTags`, `setScreenAliases`, and `Grovs.navigatorObserver` with a customizable `GrovsNavigatorObserver`.
- **[SDK error stream](https://docs.grovs.io/docs/sdk/flutter/deep-linking#handling-sdk-errors)**: `onError` with `GrovsError` and `GrovsErrorCode`. iOS only for now; Android emits nothing.
- **[Clipboard domains](https://docs.grovs.io/docs/sdk/flutter/deep-linking#clipboard-assisted-deferred-deep-linking)**: `GrovsClipboardDomains` / `grovs_clipboard_domains` for links served from your own domain.
- **[`copyToClipboardIos` / `copyToClipboardAndroid`](https://docs.grovs.io/docs/sdk/flutter/link-creation#parameters)**: per-link override of the project's copy-to-clipboard setting.

## Verifying the upgrade

Turn on info logging early in `main()`:

```dart
await Grovs().setDebugLevel('info');
```

Then check that deep links still arrive on `onDeeplinkReceived`, that `setSDK(true)` is called on launches where consent exists, and, if you added the observer, that screen views appear in the dashboard under names you recognize. Use [`setScreenAliases`](https://docs.grovs.io/docs/sdk/flutter/analytics#screen-name-aliases) to rename any that read like route types.

## See also

- [Quick Start](https://docs.grovs.io/docs/sdk/flutter/quick-start): full configuration reference
- [API Reference](https://docs.grovs.io/docs/sdk/flutter/api-reference): every property, method, and type
- [iOS SDK 3.0](https://docs.grovs.io/docs/upgrade-guides/ios-3-0) and [Android SDK 3.0](https://docs.grovs.io/docs/upgrade-guides/android-3-0): what changed in the native SDKs underneath
- [SDK Releases](https://docs.grovs.io/docs/sdk/releases): where release notes are published
