appwin_analytics 1.0.0
appwin_analytics: ^1.0.0 copied to clipboard
Product analytics for Flutter apps: sessions, screen views, custom events, crash reporting and session replay, explored in the Appwin dashboard.
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
NavigatorObserverfor 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 -
trackreturns immediately, failures degrade quietly - ✅ Comes with
appwin_core, so a singleconfigurecovers 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.