Flutter SDK
The Flutter SDK (tolinku) provides event tracking, deferred deep linking, referrals, and in-app messages for Flutter 3.10+ and Dart 3.0+.
Installation
Section titled “Installation”Add the package to your pubspec.yaml:
dependencies: tolinku: ^0.1.0Then run:
flutter pub getDependencies
Section titled “Dependencies”The SDK depends on:
httpfor network requestswebview_flutterfor rendering in-app messagesshared_preferencesfor dismiss/impression state persistence
Configure the SDK before runApp() or in your first widget’s initState:
import 'package:tolinku/tolinku.dart';
void main() { Tolinku.configure( apiKey: 'tolk_pub_your_key', // baseUrl: 'https://your-app.tolinku.com', // optional // debug: true, // optional ); runApp(MyApp());}Access the singleton anywhere:
final tolinku = Tolinku.instance;User identification
Section titled “User identification”Tolinku.instance.setUserId('user_123');
// Clear on logoutTolinku.instance.setUserId(null);Event tracking
Section titled “Event tracking”// Simple eventawait Tolinku.instance.track('custom.app_open');
// Event with propertiesawait Tolinku.instance.track('custom.purchase', properties: { 'amount': '29.99', 'currency': 'USD',});
// Force flushawait Tolinku.instance.flush();Events are batched (10 events or 5-second timer). For lifecycle-aware flushing, implement WidgetsBindingObserver:
class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState();}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver { @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); }
@override void didChangeAppLifecycleState(AppLifecycleState state) { if (state == AppLifecycleState.paused) { Tolinku.instance.flush(); } }
@override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); }}Ecommerce tracking
Section titled “Ecommerce tracking”Track purchases, cart activity, and product events via ecommerce:
Tolinku.instance.setUserId('user_123');
// Track a purchaseawait Tolinku.instance.ecommerce.purchase( transactionId: 'order_456', revenue: 49.99, currency: 'USD', items: [ TolinkuItem(itemId: 'sku_1', itemName: 'T-Shirt', price: 24.99, quantity: 2), ],);
// Track product views and cart eventsawait Tolinku.instance.ecommerce.viewItem( items: [TolinkuItem(itemId: 'sku_1', itemName: 'T-Shirt', price: 24.99)],);await Tolinku.instance.ecommerce.addToCart( items: [TolinkuItem(itemId: 'sku_1', quantity: 1)],);await Tolinku.instance.ecommerce.beginCheckout();
// Search and ratingsawait Tolinku.instance.ecommerce.search(searchTerm: 'shoes');await Tolinku.instance.ecommerce.rate(itemId: 'sku_1', rating: 4.5, maxRating: 5);
// Force flushawait Tolinku.instance.ecommerce.flush();Ecommerce events are batched (10 events or 5-second timer). The SDK manages cart IDs automatically via SharedPreferences, clearing them after purchase. For lifecycle-aware flushing, add Tolinku.instance.ecommerce.flush() to your WidgetsBindingObserver.didChangeAppLifecycleState handler alongside the regular flush.
Deep link handling
Section titled “Deep link handling”Parse incoming deep link URLs:
final result = Tolinku.parseDeepLink('https://your-app.tolinku.com/merchant/abc123');print(result.path); // "/merchant/abc123"print(result.queryParams); // {}Use Flutter’s uni_links or app_links package to listen for incoming URLs, then pass them to parseDeepLink.
Deferred deep linking
Section titled “Deferred deep linking”Claim the original link destination after the user installs your app.
Token-based claiming (Android)
Section titled “Token-based claiming (Android)”On Android, Tolinku appends a tolk_token parameter to the Play Store referrer string. After install, use the android_play_install_referrer package to read it:
import 'package:android_play_install_referrer/android_play_install_referrer.dart';
final referrerDetails = await InstallReferrer.referrer;final referrer = referrerDetails.installReferrer; // e.g. "tolk_token=abc123"final uri = Uri.parse('https://x?$referrer');final token = uri.queryParameters['tolk_token'];
if (token != null) { final link = await Tolinku.instance.deferred.claim(token: token); if (link != null) { // Navigate to link.deepLinkPath }}Signal-based claiming (iOS)
Section titled “Signal-based claiming (iOS)”On iOS, use fingerprint matching instead:
final link = await Tolinku.instance.deferred.claimBySignals( appspaceId: 'your_appspace_id', timezone: 'America/New_York', language: 'en-US', screenWidth: 390, screenHeight: 844,);Referrals
Section titled “Referrals”final referrals = Tolinku.instance.referrals;
// Create a referral codefinal result = await referrals.create(userId: 'user_123', userName: 'Jane');print(result.referralCode); // "ABC123"print(result.referralUrl); // "https://myapp.tolinku.com/ref/ABC123"
// Look up a referralfinal info = await referrals.get('ABC123');
// Link a referred user (status stays pending until reward milestone is reached)await referrals.complete( code: 'ABC123', referredUserId: 'user_456',);
// Update milestone (completes the referral if it matches the reward milestone)await referrals.milestone(code: 'ABC123', milestone: 'first_purchase');
// Claim reward (after granting it in your system)await referrals.claimReward(code: 'ABC123');
// Get leaderboardfinal leaders = await referrals.leaderboard(limit: 10);In-app messages
Section titled “In-app messages”Display messages using the built-in WebView dialog:
await Tolinku.instance.messages.show( context, trigger: 'on_open', onAction: (action) { // Handle CTA action URL }, onDismiss: () { // Message dismissed },);The SDK fetches active messages, filters out dismissed ones, and presents the highest-priority message in a full-screen WebView dialog.
Cleanup
Section titled “Cleanup”await Tolinku.instance.dispose();This flushes queued events, closes the HTTP client, and clears the singleton.