Documentation Index

Fetch the complete documentation index at: https://docs.darwinium.com/llms.txt

Use this file to discover all available pages before exploring further.

Flutter Integration

Prev Next

# Integrating the Darwinium SDK into a Flutter app

This guide covers integrating the Darwinium profiling SDK into a cross‑platform
Flutter application. Flutter has no first‑party Darwinium package, so you
bridge to the native Android and iOS SDKs through a Flutter
MethodChannel.

How it works: the native SDK collects device, network and behavioural
signals and returns a base64‑encoded profiling blob. You attach that blob to
your backend requests as a Dwn-Profiling header, where it is evaluated at the
edge or in a backend Event API call. The blob is typically 4–5 KB, so you may
need to raise any header‑length limits on your edge/proxy.


What you need

Requirement Detail
Darwinium API token Portal → Preferences → SDK Access → Generate Token. Gives a username + token used for the Maven repository.
Android minSdk 23+ (Android 6). Native SDK com.darwinium:android_sdk (this demo uses 2.4.0).
iOS iOS 12.0+ (see note below — SwiftProtobuf transitively requires 15.1). Native SDK dwn_ios_sdk via Swift Package Manager.
Maven credentials Set DWN_MAVEN_USER, DWN_MAVEN_PASSWORD, and DWN_MAVEN_URL as environment variables (preferred) or Gradle properties. Never commit credentials.

1. The Flutter (Dart) layer

Create a thin wrapper around a MethodChannel. Both platforms register a handler
on the same channel name (darwinium_sdk).

lib/darwinium_sdk.dart:

import 'dart:async';

import 'package:flutter/services.dart';

class DarwiniumSdk {
  static const MethodChannel _channel = MethodChannel('darwinium_sdk');

  Future<void> start({Map<String, Object?> config = const {}}) async {
    await _channel.invokeMethod<void>('start', {'config': config});
  }

  Future<String> collect() async {
    final value = await _channel.invokeMethod<String>('collect');
    return value ?? '';
  }
}

Use it from a page — start() once the page is up, collect() on user action:

final DarwiniumSdk _sdk = DarwiniumSdk();

@override
void initState() {
  super.initState();
  // Start after the first frame so the native engine/handler is ready.
  WidgetsBinding.instance.addPostFrameCallback((_) => _sdk.start());
}

Future<void> _onSubmit() async {
  final blob = await _sdk.collect();        // base64 profiling blob
  // Attach to your API call:
  // headers: {'Dwn-Profiling': blob}
}

See lib/main.dart for the full demo screen.


2. Android integration

2.1 Add the Maven repository and credentials

In android/build.gradle.kts, read credentials from the environment (with a
Gradle‑property fallback) and register the Darwinium Maven repo for all projects:

val dwnMavenUrl = System.getenv("DWN_MAVEN_URL")
    ?: providers.gradleProperty("DWN_MAVEN_URL").orNull
    ?: "https://packages.darwinium.com/artifactory/dwn-maven/"
val dwnMavenUser = System.getenv("DWN_MAVEN_USER")
    ?: providers.gradleProperty("DWN_MAVEN_USER").orNull
val dwnMavenPassword = System.getenv("DWN_MAVEN_PASSWORD")
    ?: providers.gradleProperty("DWN_MAVEN_PASSWORD").orNull

allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            url = uri(dwnMavenUrl)
            credentials {
                username = dwnMavenUser
                password = dwnMavenPassword
            }
        }
    }
}

Export the credentials in your shell / CI (keep these out of source control):

export DWN_MAVEN_USER=your_user
export DWN_MAVEN_PASSWORD=your_token
export DWN_MAVEN_URL=https://packages.darwinium.com/artifactory/dwn-maven/

2.2 Add the SDK dependency

In android/app/build.gradle.kts:

dependencies {
    implementation("com.darwinium:android_sdk:2.4.0")
}

2.3 Bridge Flutter → Android

In android/app/src/main/kotlin/com/example/my_app/MainActivity.kt, instantiate
DwnProfilingSDK and wire the channel. Forward permission results so the SDK can
react to location/phone‑state grants.

package com.example.my_app

import android.util.Log
import com.darwinium.dwn_sdk.DwnProfilingSDK
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel

class MainActivity : FlutterActivity() {
    private lateinit var dwnSdk: DwnProfilingSDK

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)

        dwnSdk = DwnProfilingSDK(this)

        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL)
            .setMethodCallHandler { call, result ->
                when (call.method) {
                    "start" -> {
                        val config = HashMap<String, Any>()
                        call.argument<Map<String, Any?>>("config")?.forEach { (k, v) ->
                            if (v != null) config[k] = v
                        }
                        dwnSdk.start(config, this)
                        result.success(null)
                    }
                    "collect" -> {
                        val profilingData = dwnSdk.collect()
                        Log.i(LOG_TAG, "collect() result: $profilingData")
                        result.success(profilingData)
                    }
                    else -> result.notImplemented()
                }
            }
    }

    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray,
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        dwnSdk.processPermissions(requestCode, grantResults)
    }

    companion object {
        private const val CHANNEL = "darwinium_sdk"
        private const val LOG_TAG = "DarwiniumSDK"
    }
}

3. iOS integration (Swift Package Manager)

3.1 Add the Swift package

Open ios/Runner.xcworkspace in Xcode:

  1. File → Add Package Dependencies…
  2. URL: https://packages.darwinium.com/sdk/dwn_ios_sdk.git
  3. Choose a version rule (e.g. Up to Next Major from 2.3.1).
  4. Add the dwn_ios_sdk product to the Runner target. If you skip this you
    will get module‑import errors.

3.2 Bridge Flutter → iOS

In ios/Runner/AppDelegate.swift, register the channel from
didInitializeImplicitFlutterEngine (the modern implicit‑engine entry point):

import Flutter
import UIKit
import DwnSDK_Framework

@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
  private let dwnSdk = DwnProfilingSDK()
  private static let channel = "darwinium_sdk"

  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }

  func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
    GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)

    guard let messenger = engineBridge.pluginRegistry
            .registrar(forPlugin: AppDelegate.channel)?.messenger() else { return }

    FlutterMethodChannel(name: AppDelegate.channel, binaryMessenger: messenger)
      .setMethodCallHandler { [weak self] call, result in
        guard let self else { return }
        switch call.method {
        case "start":
          let config = (call.arguments as? [String: Any])?["config"] as? [String: Any] ?? [:]
          self.dwnSdk.start(config)
          result(nil)
        case "collect":
          result(self.dwnSdk.collect())
        default:
          result(FlutterMethodNotImplemented)
        }
      }
  }
}

iOS deployment target: The framework's .swiftinterface declares
ios12.0, but it transitively imports SwiftProtobuf which requires iOS
15.1
. If Swift needs to rebuild the module from its interface you may have to
raise the deployment target accordingly.


4. Build and run

flutter pub get
flutter run -d emulator-5554          # Android
flutter run -d <ios-simulator-udid>   # iOS

5. Viewing SDK logs

Android:

adb logcat -s DarwiniumSDK

iOS simulator:

xcrun simctl spawn booted log stream --level info \
  --predicate 'eventMessage contains "DarwiniumSDK"'

6. Linking requests into a journey

For mobile flows that use ephemeral auth tokens (JWT or similar), map a
primary_session_tie value across steps so multiple requests are linked into a
single journey. Define the extraction with a JSONPath rule in your journey
configuration.


7. Troubleshooting

Symptom Fix
iOS: "Unable to resolve module dependency" Ensure the dwn_ios_sdk product is linked to the Runner target and import DwnSDK_Framework is present in AppDelegate.swift.
Android: Maven auth failure Confirm DWN_MAVEN_USER / DWN_MAVEN_PASSWORD are set and the repo URL is reachable.
Credentials in version control Keep tokens in environment variables, never in gradle.properties.