appwin_analytics

appwin_analytics measures what happens in your Flutter app: sessions, screen views and the custom events you care about, ingested by Appwin and explored in the dashboard (trends, funnels, retention).

Appwin is an engagement platform for mobile app studios. It puts an in-app support messenger, a community feed and push notifications inside your app, all rendered natively, and gives your team one dashboard to run them.

Features

  • ✅ Sessions and screen views, with a NavigatorObserver for automatic screens
  • ✅ Custom events with typed props (strings, numbers, booleans)
  • ✅ Offline-first pipeline - events persist on device and upload in batches
  • ✅ Crash reporting - native crashes, ANRs and uncaught Dart errors, grouped into issues
  • ✅ Consent-aware - relay your consent screen's verdict, buffered before init
  • ✅ Session replay - video of a share of sessions, masked on the device
  • ✅ No blocking, no throwing - track returns immediately, failures degrade quietly
  • ✅ Comes with appwin_core, so a single configure covers every product

This product draws nothing. It records what your app reports; the screens stay yours.

Installation

flutter pub add appwin_analytics

That is the only package to install. appwin_core comes with it as a dependency and is re-exported, so AppwinCore is available under the same import - do not add it yourself, or you take on a second version constraint to keep aligned with this one.

Requirements

Platform Minimum
iOS 16.0
Android 7.0 (API 24)

No repository to add: the plugin declares the native SDKs it needs, from CocoaPods (or Swift Package Manager) and Maven Central. Your app only has to meet the minimums: an iOS deployment target of 16.0 (in Xcode, plus platform :ios, '16.0' in ios/Podfile if you use CocoaPods), and minSdk = 24 in android/app/build.gradle if yours is lower.

Getting started

1. Configure the foundation at launch. This step is required, and it is the only one that is: every Appwin product reads the identity and the session it sets up.

import 'package:appwin_analytics/appwin_analytics.dart';   // re-exports AppwinCore

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await AppwinCore.instance.configure(appId: 'your-app-id');
  runApp(const MyApp());
}

2. Initialise Analytics. configure checks nothing; initialize() asks the server whether Analytics may run for this app, and answers rather than throwing.

final analytics = await AppwinAnalytics.instance.initialize();
debugPrint('Appwin Analytics: $analytics');   // ready / unavailable(plan) / ...

The verdict is cached on disk, so an offline launch falls back to the last known answer instead of dropping a product you pay for.

3. Track events from wherever they happen. The call never blocks and never throws: the event is persisted locally and uploaded in batches, offline included.

AppwinCore.instance.track('level_completed', props: {'level': 3});
AppwinCore.instance.track('purchase', props: {'value': 9.99, 'currency': 'EUR'});

AppwinCore.instance.track is the single event stream shared by every product (Analytics, Notifications automations, ad networks). AppwinAnalytics.instance.track still works but is deprecated in its favour.

Event names match ^[a-z][a-z0-9_]{0,63}$. The purchase convention (value + currency) also feeds the ad networks and the SKAN conversion value when Attribution runs.

4. Record screen views to power funnel steps and breakdowns. Let the navigator observer report every named page route:

MaterialApp(
  navigatorObservers: [AppwinNavigatorObserver()],
)

Only page routes count (dialogs and sheets do not), and a route without a name is skipped: name your routes or pass a nameExtractor. Or report a screen by hand:

AppwinAnalytics.instance.screen('checkout');

5. Relay analytics consent if your app has a consent screen. Every purpose is granted by default; unknown keeps events on the device until the answer comes, denied sends nothing. Callable before configure:

AppwinCore.instance.setConsent(
  AppwinConsentState.denied,
  purpose: AppwinConsentPurpose.analytics,
);

Crashes

Crash reporting starts with initialize(), under the same verdict and the same consent as events. It captures native crashes and ANRs through the native SDK, and uncaught Dart errors through FlutterError.onError and PlatformDispatcher.onError. Handlers you or another SDK installed earlier (Crashlytics, Sentry) keep running after Appwin's.

await AppwinAnalytics.instance.initialize(
  inAppPackages: ['my_app'],   // your packages: their frames group issues
);

try {
  await checkout();
} catch (e, stack) {
  AppwinAnalytics.instance.recordError(e, stack);   // non-fatal
}

Dart errors are reported as non-fatal: they do not stop a Flutter app. Pass crashReporting: false to initialize() to turn the whole feature off. Stacks from --obfuscate or --split-debug-info builds are sent as raw addresses and are not symbolicated yet.

Session replay

When session replay is switched on in the dashboard, initialize() records a share of the sessions as video, natively, one frame per second, under the same consent as events. Masking happens on the device, before encoding: text fields always, texts and images unless the project settings say otherwise.

await AppwinAnalytics.instance.initialize(sessionReplay: false); // never record

AppwinMask(child: Text(user.iban));         // hidden, whatever the settings
AppwinUnmask(child: Text(product.title));   // shown even when all text is masked

Text fields inside AppwinUnmask stay masked. Flutter draws everything in one surface, so the plugin walks the render tree (after the frames that change it, at most four times a second, and resent every second) and hands the rectangles to the native recorder; until the first set arrives, or when the last one is more than 2.5 s old, the whole Flutter surface is masked. What a CustomPainter draws is not detected: wrap it in AppwinMask if it shows personal data.

Documentation

License

Proprietary. Use is reserved to studios holding a current Appwin contract.

Libraries

appwin_analytics
Product analytics for Appwin.
appwin_analytics_method_channel
Default implementation of AppwinAnalyticsPlatform, over a method channel.
appwin_analytics_platform_interface
Platform contract behind AppwinAnalytics.