Watch this video for a detailed view of the integration process. We recommend that you use both the video and the written guide below.
Prerequisites
Complete these prerequisite steps before installing the Singular Flutter SDK to ensure a smooth integration process.
Required Prerequisites:
- Complete planning steps: Follow the guide in Integrating a Singular SDK: Planning and Prerequisites. These steps are mandatory for any Singular SDK integration.
- Flutter version: Verify you have a functional Flutter application with Flutter SDK installed.
- SDK credentials: Obtain your SDK Key and Secret from the Singular platform at Developer Tools > SDK Integration > SDK Keys.
Installation
Installing the SDK Package
Add the Singular Flutter SDK to your project using the pubspec.yaml dependency manager. The SDK provides Dart bindings to the native Singular SDKs for iOS and Android.
Add SDK Dependency
-
Update pubspec.yaml: Add the Singular Flutter SDK
dependency to your project's
pubspec.yamlfile:dependencies: flutter: sdk: flutter singular_flutter_sdk: ^1.8.0 -
Install dependencies: Navigate to your project directory
in the terminal and run:
flutter packages get
Platform Configuration
iOS Configuration
Complete iOS-specific setup to enable AdServices framework support for iOS attribution tracking.
Add AdServices Framework
The AdServices framework is required for Apple Search Ads attribution and iOS 14.3+ SKAdNetwork integration.
-
Navigate to iOS project: Open your Flutter project's
iOS directory and locate the Xcode workspace.
-
Navigate to the
iosfolder of your Flutter project. -
Open
Runner.xcworkspacein Xcode (use.xcworkspaceif you use CocoaPods, otherwise use.xcodeproj).
-
Navigate to the
-
Add AdServices framework: Configure the framework
in your Xcode project settings.
- In Xcode, select your project's target (e.g., "Runner").
- Go to the General tab.
- Scroll to the Frameworks, Libraries, and Embedded Content section.
- Click the + button.
-
Search for
AdServices.frameworkand add it. - Set the framework status to Optional (ensures compatibility with older iOS versions).
Why Optional? Setting AdServices as optional ensures your app remains compatible with iOS versions that don't include this framework (iOS 14.2 and earlier).
Android Configuration
Configure your Android build files to add required permissions and dependencies for proper SDK functionality.
Add Required Permissions
Add these permissions to your AndroidManifest.xml file under
the <manifest> tag to enable core SDK functionality.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="BIND_GET_INSTALL_REFERRER_SERVICE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
Important: Exclude the
com.google.android.gms.permission.AD_ID permission if
you're integrating the
Kids SDK.
This permission is required for GAID collection in standard apps
but must be omitted for apps targeting children under 13.
Samsung Galaxy Store Support
To enable install referrer tracking from Samsung Galaxy Store, add the
following to your AndroidManifest.xml:
<queries>
<package android:name="com.sec.android.app.samsungapps" />
</queries>
Transitive Dependencies
If you've disabled transitive dependencies for the Singular SDK in your Gradle configuration, manually add these required dependencies:
dependencies {
// Required for install referrer tracking
implementation 'com.android.installreferrer:installreferrer:2.2'
// Required for App Set ID
implementation 'com.google.android.gms:play-services-appset:16.0.0'
}
ProGuard Configuration
When building release APKs, ProGuard (or R8) may strip or obfuscate SDK classes. Add these keep rules to preserve Singular functionality.
Why This Matters: ProGuard is enabled by default in Flutter Android release builds. Without proper keep rules, the SDK may not function correctly in production.
-
Locate ProGuard file: Navigate to
android/app/proguard-rules.proin your Flutter project. -
Add keep rules: Append the following rules to preserve
SDK classes:
# Preserve Singular SDK classes -keep class com.singular.sdk.** { *; } # Preserve Android Install Referrer library -keep public class com.android.installreferrer.** { *; } # Uncomment if using Singular revenue tracking with Google Play Billing Library #-keep public class com.android.billingclient.** { *; }
SDK Integration
Privacy Compliance: Comply with privacy laws in your operating regions, including GDPR, CCPA, COPPA, and others when implementing the Singular SDK. For guidance, see SDK Opt-In and Opt-Out Practices.
Initialize the Singular SDK every time your app launches. SDK initialization is essential for all Singular attribution functionality and creates a new session for calculating user retention metrics.
Import SDK Classes
Import the Singular SDK classes at the top of your main application file
(typically main.dart).
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
Initialize the SDK
Create a SingularConfig object with your SDK credentials,
configure optional features, and initialize the SDK using the
start() method.
Basic Initialization
- Get credentials: Log into your Singular account and navigate to Developer Tools > SDK Integration > SDK Keys to find your SDK Key and Secret.
-
Create config: Instantiate a
SingularConfigobject with your credentials. - Add configuration: Optionally configure SDK behavior using property setters (see Configuration Reference).
-
Initialize SDK: Call
Singular.start()to start the SDK.
Initialization Example
Initialize the SDK in your app's entry point, typically within the
initState() method of your main StatefulWidget.
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
// Create configuration with credentials
SingularConfig config = SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
);
// Enable debug logging
config.enableLogging = true;
config.logLevel = 4;
// Set session timeout (in seconds)
config.sessionTimeout = 60.0;
// Initialize SDK
Singular.start(config);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
Advanced Configuration Example
Configure multiple SDK features during initialization by setting additional
properties on the SingularConfig object before calling
start().
import 'package:flutter/material.dart';
import 'package:singular_flutter_sdk/singular.dart';
import 'package:singular_flutter_sdk/singular_config.dart';
import 'package:singular_flutter_sdk/singular_link_params.dart';
import 'package:singular_flutter_sdk/singular_global_property.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
initializeSingularSDK();
}
void initializeSingularSDK() {
// Create configuration with credentials
SingularConfig config = SingularConfig(
'YOUR_SDK_KEY',
'YOUR_SDK_SECRET'
);
// User identification
config.customUserId = 'user_123456';
// Privacy settings
config.limitDataSharing = false;
// Deep linking handler
config.singularLinksHandler = (SingularLinkParams params) {
print('Deep link received: ${params.deeplink}');
print('Passthrough params: ${params.passthrough}');
print('Is deferred: ${params.isDeferred}');
// Handle navigation based on deep link
};
// Short link timeout
config.shortLinkResolveTimeOut = 10.0;
// Facebook integration
config.facebookAppId = 'YOUR_FACEBOOK_APP_ID';
// SKAdNetwork settings (iOS)
config.skAdNetworkEnabled = true;
config.manualSkanConversionManagement = false;
config.waitForTrackingAuthorizationWithTimeoutInterval = 30;
// Conversion value callbacks (iOS)
config.conversionValueUpdatedCallback = (int conversionValue) {
print('Conversion value updated: $conversionValue');
};
config.conversionValuesUpdatedCallback = (int cv, int coarse, bool lock) {
print('Fine: $cv, Coarse: $coarse, Locked: $lock');
};
// Global properties
config.globalProperties = [
SingularGlobalProperty('app_version', '2.5.0', true),
SingularGlobalProperty('user_tier', 'premium', false)
];
// Debugging
config.enableLogging = true;
config.logLevel = 4;
// Session timeout
config.sessionTimeout = 60.0;
// Initialize SDK
Singular.start(config);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(),
);
}
}
Configuration Reference: For a complete list of available configuration options, see the Flutter SDK Configuration Reference.
Critical: Do NOT use the Singular Reporting API Key. Only use the SDK-specific credentials from the SDK Integration page. Using wrong credentials prevents data from reaching Singular.