Skip to main content

softlink_flutter 0.0.13 copy "softlink_flutter: ^0.0.13" to clipboard
softlink_flutter: ^0.0.13 copied to clipboard

SoftLink Flutter SDK for deep linking, deferred deep linking, and install attribution.

softlink_flutter #

Official Flutter SDK for SoftLink — a deep link management platform.

Features #

  • 🔗 Deep linking (when app is already installed)
  • 📦 Deferred deep linking (when app is not installed)
  • 📱 Device-level install attribution (GAID on Android / IDFA + IDFV on iOS)
  • 🎯 Snapchat CAPI integration support
  • 🔄 Automatic duplicate URI handling
  • 💾 Persistent storage via GetStorage

Installation #

dependencies:
  softlink_flutter: ^0.0.13

Usage #

Initialize the SDK in your main.dart:

import 'package:softlink_flutter/softlink_flutter.dart';

void main() {
  runApp(MyApp());
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    SoftLink.init(
      baseUrl: 'https://your-softlink-backend.com',
      apiKey: 'sl_your_api_key',
      onDeepLink: (deepLink) {
        if (deepLink == null) return;
        print('Screen: ${deepLink.screen}');
        print('Params: ${deepLink.params}');
      },
    );
  }
}

Use SoftLink.generateReferralLink() to generate shareable deep links at runtime:

// Without token (finds first dynamic link matching screenKey):
final url = await SoftLink.generateReferralLink(
  screenKey: 'PRODUCT_DETAIL',
  values: {'productId': '209', 'categoryId': '220'},
  referrerId: currentUser.id, // optional
);

// With token (targets a specific dynamic link):
final url = await SoftLink.generateReferralLink(
  screenKey: 'PRODUCT_DETAIL',
  values: {'productId': '209', 'categoryId': '220'},
  token: 'PARENT_TOKEN', // from SoftLink portal
  referrerId: currentUser.id,
);

if (url != null) {
  Share.share(url); // share via any app
}

Trigger Events #

Trigger custom events defined in the SoftLink portal to track user actions tied to deep links.

Go to your app → Events → Create event with a key (e.g. PURCHASE) and define metadata fields.

String? _deepLinkToken;

SoftLink.init(
  baseUrl: 'https://api.supersoftlink.com',
  apiKey: 'sl_your_api_key',
  onDeepLink: (deepLink) {
    if (deepLink == null) return;
    _deepLinkToken = deepLink.token; // save token
    navigateTo(deepLink.screen, deepLink.params);
  },
);

Step 3 — Trigger event when user completes action #

await SoftLink.triggerEvent(
  eventKey: 'PURCHASE',          // must match key defined in portal
  linkToken: _deepLinkToken,     // associates event with the deep link
  sequence: 1,                   // optional: order of event in user journey
  lastEventKey: 'VIEW_ITEM',     // optional: previous event key
  metadata: {
    'item_id': 'item-001',
    'amount': '99.00',
    'currency': 'USD',
  },
);

// Clear token after event
_deepLinkToken = null;

Step 4 — Clear token when screen is disposed #

@override
void dispose() {
  _deepLinkToken = null; // clear if user leaves without completing action
  super.dispose();
}

Parameters #

Parameter Type Required Description
eventKey String ✅ Yes Event key defined in SoftLink portal (UPPERCASE_WITH_UNDERSCORES)
linkToken String? No Deep link token to associate event with a link. If not passed, event is tracked as organic
sequence int? No Order of this event in the user journey, defined by developer
lastEventKey String? No Previous event key fired before this one
metadata Map<String, dynamic>? No Key-value pairs matching the metadata schema defined in portal

Notes #

  • Event key must exist in SoftLink portal and be set to Active status ✅
  • If linkToken is not passed, event is counted as organic (no link attribution) ✅
  • Metadata fields should match the schema defined in the portal ✅
  • Events are visible in SoftLink portal under app → Events → Analytics ✅

Set User Data (Signal Quality) #

Call SoftLink.setUserData() after user logs in to improve ad platform signal quality. Email and phone are SHA256 hashed before sending — never sent in plain text.

Note: GAID (Android) is collected automatically by the SDK on init. IDFA (iOS) is passed via SoftLink.init(idfa: idfa) after ATT permission. You do not need to pass MAID manually.

// Call after user logs in
await SoftLink.setUserData(
  email: 'user@example.com',   // will be SHA256 hashed
  phone: '+1234567890',         // will be SHA256 hashed
);

Parameters #

Parameter Type Required Description
email String? No User email — automatically lowercased, trimmed and SHA256 hashed
phone String? No User phone number — spaces and dashes removed, then SHA256 hashed
maid String? No Optional — only needed if you manage MAID manually. GAID (Android) and IDFA (iOS via ATT) are handled automatically by the SDK

Notes #

  • Call this once after user logs in ✅
  • GAID on Android is automatically collected on SoftLink.init() ✅
  • IDFA on iOS is passed via SoftLink.init(idfa: idfa) after ATT permission ✅
  • Data is used to improve Snapchat, Meta and TikTok CAPI signal quality ✅
  • Never pass pre-hashed values — SDK handles hashing automatically ✅

App Open Tracking #

The SDK automatically calls reportAppOpen() on every SoftLink.init() — no additional code needed.

This fires an APP_OPEN event to connected ad platforms (Snapchat, Meta, TikTok) with real device info including OS version, device model and locale for improved signal quality.

// This is called automatically on init — no extra code needed
await SoftLink.init(
  baseUrl: 'https://your-softlink-backend.com',
  apiKey: 'sl_your_api_key',
  onDeepLink: (deepLink) { ... },
);
// APP_OPEN event fires automatically ✅

What is sent #

  • Device platform (Android/iOS)
  • OS version
  • Device model
  • Locale
  • Device ID
  • Hashed email/phone (if previously set via setUserData())
  • MAID/IDFA (if available)

Android Setup #

Add to android/app/src/main/AndroidManifest.xml inside <activity>:

<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:scheme="https" android:host="your-domain.com" android:pathPrefix="/l/"/>
</intent-filter>
<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <data android:scheme="yourscheme" android:host="l"/>
</intent-filter>

Add to MainActivity.kt:

override fun onNewIntent(intent: Intent) {
    super.onNewIntent(intent)
    setIntent(intent)
}

iOS Setup #

Add to Runner.entitlements:

<key>com.apple.developer.associated-domains</key>
<array>
  <string>applinks:your-domain.com</string>
</array>

Add to Info.plist:

<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>yourscheme</string>
    </array>
  </dict>
</array>

Add to AppDelegate.swift:

// Handle Universal Links when app is already running
override func application(
  _ application: UIApplication,
  continue userActivity: NSUserActivity,
  restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
  return super.application(application, continue: userActivity, restorationHandler: restorationHandler)
}

// Handle custom scheme URLs when app is already running
override func application(
  _ app: UIApplication,
  open url: URL,
  options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
  return super.application(app, open: url, options: options)
}

iOS Deferred Deep Linking (IDFA) #

By default, SoftLink uses IDFV (Identifier for Vendor) for iOS deferred deep linking. For improved accuracy, you can pass the IDFA (Identifier for Advertisers) when the user grants App Tracking Transparency (ATT) permission.

Why IDFA improves accuracy #

  • IDFV — available without permission but resets when all vendor apps are uninstalled
  • IDFA — persistent unique device identifier, works even when IP changes (CGNAT), much more reliable for install attribution

Note for Android: GAID (Google Advertising ID) is collected automatically by the SDK — no additional setup required. ✅

Implementation #

Step 1 — Add ATT package to your app:

dependencies:
  app_tracking_transparency: ^2.0.6

Step 2 — Add to ios/Runner/Info.plist:

<key>NSUserTrackingUsageDescription</key>
<string>We use this identifier to improve your app experience and provide relevant content.</string>

Step 3 — Request ATT and pass IDFA to SDK:

import 'dart:io';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:softlink_flutter/softlink_flutter.dart';

@override
void initState() {
  super.initState();
  WidgetsBinding.instance.addPostFrameCallback((_) async {
    String? idfa;

    if (Platform.isIOS) {
      try {
        final status = await AppTrackingTransparency.trackingAuthorizationStatus;
        if (status == TrackingStatus.notDetermined) {
          await Future.delayed(const Duration(milliseconds: 500));
          final result = await AppTrackingTransparency.requestTrackingAuthorization();
          if (result == TrackingStatus.authorized) {
            idfa = await AppTrackingTransparency.getAdvertisingIdentifier();
            if (idfa == '00000000-0000-0000-0000-000000000000') idfa = null;
          }
        } else if (status == TrackingStatus.authorized) {
          idfa = await AppTrackingTransparency.getAdvertisingIdentifier();
          if (idfa == '00000000-0000-0000-0000-000000000000') idfa = null;
        }
      } catch (_) {}
    }

    await SoftLink.init(
      baseUrl: 'https://your-softlink-backend.com',
      apiKey: 'sl_your_api_key',
      idfa: idfa, // pass IDFA when available
      onDeepLink: (deepLink) {
        if (deepLink == null) return;
        // handle navigation
      },
    );
  });
}

Notes:

  • ATT permission is optional — SDK falls back to IDFV if IDFA is unavailable ✅
  • Show ATT prompt at the right time — avoid conflicts with notification permission dialogs ✅
  • Apple requires NSUserTrackingUsageDescription in Info.plist — App Store will reject without it ✅
  • IDFA is only available on iOS — Android uses Android ID automatically ✅

License #

Apache

2
likes
140
points
392
downloads

Documentation

API reference

Publisher

verified publishersupersoft.com.pk

Weekly Downloads

SoftLink Flutter SDK for deep linking, deferred deep linking, and install attribution.

Repository (GitHub)
View/report issues

License

Apache-2.0 (license)

Dependencies

app_links, crypto, device_info_plus, flutter, get_storage, http

More

Packages that depend on softlink_flutter

Packages that implement softlink_flutter