Mobile
Flutter plugin
This page is assembled from
sdks/flutter/README.mdin the repository. See the SDK overview for the choice between native SDKs and wrappers.
Formerly
dtrackier_flutter. Until 2.0 the deprecatedDTrackiertypedef forwards toMetrixed; change the dependency and import topackage:metrixed_flutter/metrixed_flutter.dart.
metrixed_flutter is a thin plugin over the native Android and iOS SDKs.
All tracking logic (offline queue, request signing, attribution, SKAdNetwork, consent enforcement) lives in the native
SDKs; the plugin validates arguments and forwards them over a MethodChannel / EventChannel. Method names mirror
the native SDKs. Android min API 21, iOS 13.
Install
dependencies:
metrixed_flutter: ^1.0.0
Android resolves com.metrixed:metrixed-android from Maven Central (until published, add the Maven-layout repo from
make sdk-android-build to your root build.gradle). iOS pulls the Metrixed pod through the plugin podspec.
Platform setup is the same as for the native SDKs:
- Android: a VIEW intent filter for your scheme / App Links on the main activity; kids apps also add
<uses-permission android:name="com.google.android.gms.permission.AD_ID" tools:node="remove" />. - iOS:
NSUserTrackingUsageDescription,SKAdNetworkItems,NSAdvertisingAttributionReportEndpoint, Associated Domainsapplinks:go.yourdomain.com, URL scheme (see the iOS README). Flutter forwardsopen urland Universal Links to the SDK through the plugin's application-delegate hooks.
Initialise
import 'package:metrixed_flutter/metrixed_flutter.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Metrixed.initialize(const DTConfig(
appToken: 'APP_TOKEN',
environment: DTEnvironment.production, // sandbox: flagged on every payload, excluded from billing
baseUrl: 'https://ingest.example.com',
secret: 'SDK_SECRET', // request signing
));
runApp(const MyApp());
}
Dart starts after the first Android activity is visible: the install is reported immediately but the very first
session starts at the next foreground. To count it too, initialise the native SDK in Application.onCreate
instead of calling initialize.
Platform-specific options are ignored on the other platform: secretId, consentRequired, collectGaid,
collectAppSetId, collectAndroidId, oaid, preloadKey, referrerTimeoutMs (Android); trackingBaseUrl,
attWaitInterval, readIdfa, readIdfv, linkMe*, skanEnabled, storeKitForwarding (iOS). kidsMode maps to
setKidsMode / coppaCompliant.
Events and ad revenue
Metrixed.trackEvent(const DTEvent('level_up', callbackParams: {'level': '5'}));
Metrixed.trackEvent(DTEvent('purchase', revenue: 9.99, currency: 'USD', dedupeId: orderId, partnerParams: {'af_content': 'x'}));
Metrixed.trackAdRevenue(const DTAdRevenue('applovin_max', revenue: 0.012, currency: 'USD', adUnit: 'u1', adType: 'rewarded'));
Metrixed.setCustomerUserId('user-42');
Revenue is a number plus an ISO currency (required together), formatted by the native SDK as a 6-decimal string.
Invalid arguments throw ArgumentError before anything reaches native code. Ad revenue: call trackAdRevenue from your
mediation callback (MAX ad.revenue / networkName, LevelPlay impressionData.revenue, AdMob valueMicros / 1e6
with currencyCode).
Deep links
Metrixed.setDeeplinkHandler((link) => router.go(link.deepLinkValue ?? link.url)); // or: Metrixed.deeplinks.listen(...)
await Metrixed.processDeeplink(url); // links you receive yourself
Direct (scheme / App Link / Universal Link) and deferred links arrive as DTDeeplink(url, source, clickId, deepLinkValue, params). Links that arrive before the first listener are held natively and delivered on subscribe.
Android handles onNewIntent and the launching intent itself.
Consent and privacy
Metrixed.setConsent(const DTConsent(thirdPartySharing: false, measurement: true, adPersonalization: false, gdprApplies: true, tcf: tcString));
Metrixed.setThirdPartySharing(false);
Metrixed.gdprForgetMe(); // server erase + local wipe; the SDK stays off afterwards
tcf, gpp, googleDma, metaLdu are honoured on iOS; Android carries thirdPartySharing, measurement,
adPersonalization, gdprApplies. setPushToken takes the FCM token (Android) or the hex APNs token (iOS).
Platform differences
| Call | Android | iOS |
|---|---|---|
setExternalDeviceId | yes | set externalDeviceId in DTConfig (call is a no-op) |
setEnabled, setOfflineMode, setSecret | yes | no-op |
getAttribution, attributions / setAttributionListener | yes | null / never fires |
Tests and CI
make sdk-flutter-test (not part of make test), in the pinned Flutter 3.24.5 image: flutter analyze, Dart tests with
a mocked channel and the shared wire vectors (sdks/test-vectors/wrapper-api.json), flutter pub publish --dry-run
validation, and a debug APK build of example/ which compiles the Kotlin bridge against the real AAR. The iOS side
builds in the macOS job of .github/workflows/sdk-wrappers.yml. Request signing is done and tested by the native SDKs.
Sample: example/. Changelog: CHANGELOG.md.