Skip to main content
Supported on: iOS SDK 1.0.61+ · Android SDK 1.0.33+ · Flutter SDK 1.0.3+

Requirements

Before integrating the AppDNA Flutter SDK, ensure your project meets the following minimum requirements:
The Flutter SDK uses platform channels to delegate rendering, storage, and network I/O to the native iOS and Android SDKs under the hood, so every paywall, onboarding flow, and in-app message looks and feels platform-native. Your project must meet the native platform requirements as well.

Installation

Add the AppDNA SDK to your pubspec.yaml:
Then install dependencies:

Firebase Configuration

The AppDNA SDK uses Firebase Firestore for configuration delivery (paywalls, experiments, feature flags, onboarding flows). You must add Firebase configuration files for each platform your app targets.

Step 1: Download Firebase Config Files

  1. Log into your AppDNA Console
  2. Go to Settings → SDK
  3. Click Download Firebase Config to download both:
    • GoogleService-Info-AppDNA.plist (for iOS)
    • google-services-appdna.json (for Android)

Step 2: Add iOS Configuration

  1. Open ios/Runner.xcworkspace in Xcode
  2. Drag GoogleService-Info-AppDNA.plist into the Runner folder in the project navigator
  3. Ensure “Copy items if needed” is checked
  4. Select the Runner target in the “Add to targets” section

Step 3: Add Android Configuration

Place the google-services-appdna.json file in the Android app module directory:
Ensure the Google Services plugin is applied in your android/app/build.gradle:
And the classpath is added to android/build.gradle:

Step 4: Add firebase_core Dependency

Add firebase_core to your pubspec.yaml:
Then install dependencies:
Without the Firebase config files, the SDK cannot fetch remote configuration (paywalls, experiments, feature flags). Events will still be tracked, but remote features will not work.
If your app already uses Firebase for your own services (Realtime Database, Analytics, Crashlytics), AppDNA automatically initializes a separate named Firebase instance using GoogleService-Info-AppDNA.plist (iOS) and google-services-appdna.json (Android). Your existing Firebase setup is not affected. Just add the AppDNA config files alongside your own.

Architecture

The appdna_sdk package uses Flutter platform channels for rendering, storage, and network I/O. The Dart layer marshals method calls and streams events from the native side, so every feature reaches your Flutter app at native performance with native UI primitives.

Platform Channels

The SDK registers the following platform channels:
You do not need to interact with platform channels directly. The AppDNA class and its module accessors provide a high-level Dart API that wraps all channel communication.

Native Dependencies

The Flutter SDK inherits the dependencies of the underlying native SDKs. These are resolved automatically by CocoaPods (iOS) and Gradle (Android):
If your project already includes these dependencies, ensure your version constraints are compatible with the versions above. CocoaPods and Gradle will resolve conflicts automatically in most cases.
Lottie and Rive animation support is provided by the native SDKs. On iOS, add lottie-ios and rive-ios to your Podfile if you use those formats. On Android, the equivalent dependencies are bundled with the native AppDNA SDK.

Import

Import the SDK in any Dart file where you need to use it:
This single import exposes the AppDNA entry point, every module accessor, the canonical delegate interfaces (AppDNAPushDelegate, AppDNAPaywallDelegate, AppDNAOnboardingDelegate, etc.), and all DTOs (Entitlement, ProductInfo, PurchaseResult, PaywallContext, …).

Interactive maps

An onboarding step can contain a map. The static map needs no setup — the provider key is delivered with your configuration.
Enable the Maps SDK for this platform in Google Cloud, alongside the Maps Static API the map image already uses: APIs & Services → Library → Maps SDK for iOS and Maps SDK for Android. Pan & zoom is drawn by that SDK, so without it enabled the key is rejected at map start and the step falls back to the still image — every bit of wiring below can be correct and the map still will not move. See Maps for the full key setup.
A pannable map needs one line in your Android host, and nothing at all on iOS. The Maps SDK for Android reads its key from the merged manifest at build time, so add this to android/app/src/main/AndroidManifest.xml:
Without it the SDK falls back to the static map rather than rendering a grey rectangle, so nothing breaks — the map simply does not pan. The key is always yours; AppDNA never substitutes one of its own, because Google bills the account that owns it.
Your Podfile needs use_frameworks! — the iOS SDK cannot be built from pods built as static libraries (iOS installation), and Flutter’s generated Podfile has it. With dynamic frameworks (plain use_frameworks!, not :linkage => :static), add this to it. Google ships the Maps SDK as a static xcframework, and CocoaPods refuses a static binary inside a dynamically-linked target:
That validation guards against the same static code being embedded in several dynamic frameworks. With one consumer — your app — that cannot happen, which is why this is the standard remedy across the GoogleMaps ecosystem.And name the pod in your app target too, inside the target '<YourApp>' do block:
The two lines do different jobs and you need both. The pre_install block lets pod install finish; it does not make CocoaPods link a static framework that reached your app transitively. Without this second line the app compiles and then fails at the linker with Undefined symbols ... _OBJC_CLASS_$_GMSCameraPosition. react-native-maps asks for the same line, for the same reason.
None of this applies to Swift Package Manager. An iOS app that adds AppDNASDK through SPM gets the map engine linked automatically, with no Podfile and nothing to add.

Verify Installation

After adding the dependency, verify the SDK is correctly installed by printing the version:
You should see a version string printed in the debug console. If the import fails, run flutter pub get again and restart your IDE.

Troubleshooting

If you encounter issues during integration, call AppDNA.diagnose() after configuration to get a full health report:
This prints a diagnostic report to the platform console (Xcode debug area on iOS, Logcat on Android):
Any items marked with ❌ indicate a configuration issue. Common fixes: For more verbose output, set AppDNAOptions(logLevel: AppDNALogLevel.debug) during development to surface SDK activity.

Next Steps

Once the SDK is installed, proceed to the Quickstart guide to configure the SDK and start tracking events.