Install the SDK
Add the Embrace Flutter SDK
Add the Embrace SDK to your project
Add the Embrace package to your pubspec.yaml:
flutter pub add embrace
iOS setup
This affects your Flutter app's iOS build only; Android is unchanged. Your iOS build gets the Embrace Apple SDK through CocoaPods, and CocoaPods trunk stops accepting new Podspecs on December 2, 2026. Existing builds keep resolving, but after that date new Embrace iOS versions and fixes are only available through Swift Package Manager, so plan your move before then. Full schedule and migration steps.
Choose an iOS dependency manager
As of Flutter 3.44 (May 18, 2026), Swift Package Manager is the default dependency manager for iOS and macOS, and upgrading Flutter adds the integration automatically. On earlier Flutter versions you can opt in with flutter config --enable-swift-package-manager. The Embrace Flutter SDK supports Swift Package Manager as of 4.9.0.
Note that Flutter still falls back to CocoaPods for any plugin that doesn't yet ship Swift Package Manager support, so your project may use both during the transition.
Swift Package Manager support requires Embrace Flutter SDK 4.9.0 or later and Flutter 3.44.0 or later — the first Flutter release with the FlutterFramework Swift package that Flutter plugins build against. If you're on an earlier Embrace Flutter SDK version, run flutter pub upgrade embrace; if you're on an earlier Flutter version, upgrade Flutter or opt in early with flutter config --enable-swift-package-manager.
The embrace_ios plugin ships both a Package.swift and a podspec, so Flutter's iOS build tooling automatically picks up whichever one matches your project's dependency manager when it resolves plugins — the same as it does for any other Flutter plugin. You don't need to add anything to your Podfile or Runner.xcodeproj yourself.
If you're migrating an existing project from CocoaPods to Swift Package Manager, follow Flutter's own migration guide — there's no separate Embrace-specific step. Flutter moves your plugin dependencies, including Embrace's, out of the Podfile and into Package.swift for you.
Initialize the SDK
Log in to the Embrace dashboard and create a project. The dashboard contains the app ID and API token that you need for configuring your integration.
Then modify your AppDelegate to initialize Embrace in the init function:
import EmbraceIO
import EmbraceCore
import EmbraceCrash
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override init() {
super.init()
do {
try Embrace
.setup(
options: Embrace.Options(
appId: "", // Your App ID from Embrace Dash
platform: .flutter
)
)
.start()
} catch let e {
print("Error starting Embrace \(e.localizedDescription)")
}
}
}
Upload symbol files
Embrace requires your application's dSYM symbol files to make stacktraces from crashes human-readable.
On the Xcode Build Phases tab, add a new run script. You can find your 5-character app ID and API token in the Embrace dashboard.
If you are using Swift Package Manager, download the support utility from https://downloads.embrace.io/embrace_support.zip, extract it, and place the scripts in your project:
EMBRACE_ID={YOUR_APP_ID} EMBRACE_TOKEN={YOUR_API_TOKEN} "${SRCROOT}/path/to/your/run.sh"
If you are using CocoaPods, the run.sh script is bundled with the SDK:
EMBRACE_ID={YOUR_APP_ID} EMBRACE_TOKEN={YOUR_API_TOKEN} "${PODS_ROOT}/EmbraceIO/run.sh"
The ${PODS_ROOT} path only exists in a CocoaPods integration. When you migrate to Swift Package Manager, switch this build phase to your own copy of run.sh.
Also ensure that DEBUG_INFORMATION_FORMAT is set to DWARF with dSYM File in your Build Settings. For more details, see the iOS dSYM Upload guide.
Android setup
In the root-level build.gradle file, add the embrace-swazzler dependency:
buildscript {
repositories {
mavenCentral()
google()
}
dependencies {
classpath "io.embrace:embrace-swazzler:${findProject(':embrace_android').properties['emb_android_sdk']}"
}
}
In the app/build.gradle file, add:
apply plugin: 'com.android.application'
apply plugin: 'embrace-swazzler'
In app/src/main, add a config file named embrace-config.json. You can find your 5-character app ID and API token in the Embrace dashboard:
{
"app_id": "{YOUR_APP_ID}",
"api_token": "{YOUR_APP_TOKEN}",
"ndk_enabled": true,
"sdk_config": {
"app_framework": "flutter"
}
}
Import Embrace
Import Embrace in the file where your main() function exists:
import 'package:embrace/embrace.dart';
Add the Flutter SDK start call
Wrap the entire contents of your main() function in Embrace.instance.start(). This is essential if you want Embrace to capture Dart errors.
import 'package:embrace/embrace.dart';
Future<void> main() async {
await Embrace.instance.start(() => runApp(const MyApp()));
}
Add the Android SDK start call
The call to start the Embrace Android SDK should be placed in the onCreate method of an Application subclass:
import android.app.Application
import io.embrace.android.embracesdk.Embrace
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
Embrace.getInstance().start(this)
}
}
Build and run the application
Now you're ready to build and run the application. When the app launches, check the system logs and look for Embrace to print its version number:
Embrace Flutter SDK Version: 4.2.0
If you encounter any errors, reach out on Slack and we can help.
Trigger a session upload
To trigger a session upload, send the application to the background. The SDK usually has enough time to upload the session, but sometimes the app can't complete the upload in the background. To ensure the session was uploaded, launch the application again and refresh the dashboard in your browser. You should see that you've moved on to the next step.