Install via pubspec
Add the package and fetch dependencies:
dependencies:
sddl_sdk: ^0.1.2 # use the latest published version
flutter pub get
iOS setup (Universal Links)
Enable Associated Domains in Xcode (Target → Signing & Capabilities → + Capability → Associated Domains) and add:
applinks:{YOUR_ID}.sddl.me
# or
applinks:{your.custom.domain}
SDDL can auto-publish apple-app-site-association from your app settings.
After changing entitlements, delete and reinstall the app to refresh Universal Links.
Android setup (App Links)
Declare an intent filter for your verified domain. SDDL can host assetlinks.json based on your package
name and SHA-256 fingerprints configured in the dashboard.
<uses-permission android:name="android.permission.INTERNET" />
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop">
<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_ID}.sddl.me OR {your.custom.domain}"
android:pathPrefix="/" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Get SHA-256 fingerprints
# Debug
keytool -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore -storepass android -keypass android
# Release
keytool -list -v -alias YOUR_ALIAS -keystore /path/to/your-release-key.jks
Usage (minimal)
Initialize once (e.g., in your root widget) and handle the payload to route users to the correct screen.
import 'package:flutter/material.dart';
import 'package:sddl_sdk/sddl_sdk.dart';
import 'package:sddl_sdk/models/link_data.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
Sddl.init(
onSuccess: _onDeepLink,
onError: (err) => debugPrint('SDDL error: $err'),
);
}
@override
void dispose() {
Sddl.dispose();
super.dispose();
}
void _onDeepLink(LinkData data) {
// navigatorKey.currentState?.pushNamed('/product', arguments: data.metaData);
debugPrint('SDDL payload: ${data.toString()}');
}
@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: navigatorKey,
home: const Scaffold(
body: Center(child: Text('Ready for deep links')),
),
);
}
}
Tip: for cold-start reliability on iOS ad traffic you can use an optional intermediate web page.
Troubleshooting
- iOS: Associated Domains must be verified; after changes, delete & reinstall the app. Confirm AASA is reachable.
- Android: host in the intent filter must match your deep link domain; set
android:autoVerify="true"; add correct SHA-256 fingerprints in SDDL. - Domains: use your verified custom domain or
{YOUR_ID}.sddl.meconfigured in SDDL. - SDK init: call
Sddl.initonce; pair withSddl.disposewhen appropriate.
FAQ
Do I need to host AASA or assetlinks.json?
No. SDDL can publish both from your app settings.
Can I use a custom domain?
Yes. Connect and verify your domain in SDDL, then use it in your iOS/Android configuration.
Is the SDK required?
No. You can use a REST-only flow. The SDK simplifies Universal/App Link handling and cold start.