asalyze (Flutter)
Apple Search Ads ROAS tracking for iOS Flutter apps. A self-contained plugin: the native Asalyze
Swift SDK (AdServices attribution, StoreKit 2 purchases, ad revenue) is vendored into the plugin's iOS
pod and compiled in — no external pods, no CocoaPods trunk dependency. Dart just calls in.
iOS only. Apple Search Ads attribution is an iOS capability, so there is no Android implementation (every call is a no-op off iOS). Requires iOS 15+.
Install (embed in another Flutter project)
Point your app's pubspec.yaml at this plugin. Local path (same machine) is easiest for now:
dependencies:
asalyze:
path: /Volumes/Office/Development/MMP/sdk/flutter
…or via git once pushed:
dependencies:
asalyze:
git:
url: https://github.com/<you>/asalyze-flutter.git
Then flutter pub get and (from ios/) pod install. Ensure the app's iOS deployment target is 15.0+.
Use
import 'package:asalyze/asalyze.dart';
// Call once, as early as possible (e.g. top of main(), before runApp).
await Asalyze.configure(
apiKey: 'sk_…', // Asalyze dashboard → My Apps → app → SDK API key
appId: 'com.your.app', // your bundle id
// endpoint: 'http://your-mac.local:3100', // ← only for local/staging; omit for production
);
// StoreKit 2 purchases/renewals/refunds are captured NATIVELY — there is nothing to call.
// Apple's own transaction id, price, currency, offer type and product type are used.
// Ad revenue (e.g. from AdMob's paid-event callback):
await Asalyze.trackAdRevenue(valueUsd: 0.012, format: AdFormat.banner);
// Custom Goal events + optional user id:
await Asalyze.trackEvent('completed_onboarding');
await Asalyze.setUserId('user_123');
Local backend testing (dev)
To point at a backend running on your Mac instead of production:
- Pass
endpoint:toconfigure— use the Mac's.localhostname (survives IP changes), e.g.http://your-mac.local:3100. On a real devicelocalhostwill NOT work (that's the phone). - iOS blocks plain HTTP — add to the app's
ios/Runner/Info.plist(debug only, never ship):
Accept the iOS "Local Network" permission prompt on first launch.<key>NSAppTransportSecurity</key> <dict><key>NSAllowsArbitraryLoads</key><true/></dict> <key>NSLocalNetworkUsageDescription</key> <string>Connects to the local Asalyze dev server for testing.</string> - Phone and Mac on the same Wi-Fi. A dev build reports as
sandbox→ data lands in the dashboard's Test Devices → Live sandbox feed, not production Reports.
Maintaining the vendored native SDK
The native Swift sources under ios/Classes/native/ are a vendored copy of the canonical SPM package
at ../Sources/Asalyze (the source of truth). After changing the native SDK, re-vendor with:
./sync-native.sh
Known limitations
- No offline queue / retry yet — ingest is fire-and-forget (events lost on a network failure).
- Default endpoint is
https://asalyze.com(live) — passendpoint:only for local/staging testing.
Subscription transitions you report yourself (you probably don't need this)
Asalyze.trackSubscription(...) exists for the four transitions the SDK cannot observe on device —
cancelled, expired, resubscribed, offer redeemed. StoreKit's transaction stream only carries
purchases, renewals, refunds and trial starts, and renewal status is not a transaction at all.
Almost nobody should call it. Those four transitions already reach Asalyze through App Store Server Notifications, which also cover users who never reopen the app. Configure those and this API has nothing left to do.
Two rules if you do use it:
- Never report a purchase, renewal, refund or trial start. StoreKit reports those automatically, with Apple's own price, currency and transaction id. Reporting them again counts the money twice.
- Pass the transaction id whenever there is a price. It is the key the backend deduplicates on, so the same money reported twice is booked once. Without it, a priced event is booked unconditionally.