Initialization Strategies

Strategies for initializing the Kotlin Multiplatform SDK.

When it comes to initializing a Kotlin Multiplatform SDK, there are multiple strategies to consider:

Regardless of the initialization strategy you choose, it's important to place the initialization code at an early lifecycle stage of your application to ensure the SDK is set up correctly before it is used. Here are general guidelines for placing the initialization code for different platforms:

MainActivity.kt
Copied
import your.kmp.app.initializeSentry

class YourApplication : Application() {
  override fun onCreate() {
    super.onCreate()
      initializeSentry()
   }
}

AppDelegate.swift
Copied
import shared

func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil
) -> Bool {
    AppSetupKt.initializeSentry()
    return true
}

Requires Sentry SDK version 0.7.1 or higher.

This approach involves initializing the SDK with the platform's specific options directly, using PlatformOptionsConfiguration. This strategy is ideal for projects that require configuring options that are not yet supported by the KMP SDK, such as experimental options. For example, if you configure your KMP application for Android, you will have access to every option that the Android SDK provides.

In order to be able to use the native platform options with Apple targets, you need to opt-in to ExperimentalForeignApi.

build.gradle.kts
Copied
kotlin {
    // other configuration ...
  sourceSets {
    all {
        languageSettings.optIn("kotlinx.cinterop.ExperimentalForeignApi")
    }
  }
}

SentrySetup.kt
Copied
import io.sentry.kotlin.multiplatform.Sentry
import io.sentry.kotlin.multiplatform.PlatformOptionsConfiguration

fun initializeSentry() {
  Sentry.initWithPlatformOptions(platformOptionsConfiguration())
}

expect fun platformOptionsConfiguration(): PlatformOptionsConfiguration

The shared initializer approach involves initializing the SDK in your shared codebase, using the same configuration options for all platforms. This approach is ideal for projects that prioritize consistency across platforms and do not require platform-specific customizations.

Using a shared initializer provides a single source of truth for your SDK's configuration options. This can simplify maintenance and debugging efforts, as you only need to update one codebase for all platforms.

To initialize the SDK, create a Kotlin file in your commonMain (such as AppSetup.kt or whatever you decide to call it), and write an initialization function. You'll then be able to call it in an early lifecycle stage in your platforms.

AppSetup.kt
Copied
import io.sentry.kotlin.multiplatform.Sentry

// Application context is only needed for Android targets
fun initializeSentry() {
  val configuration: (SentryOptions) -> Unit = {
    it.dsn = "https://examplePublicKey@o0.ingest.sentry.io/0"
    // Add common configuration here
  }
  Sentry.init(configuration)
}

Platform-specific initializers allow for customization of the SDK's configuration options on a per-platform basis. This approach can be particularly useful when your SDK requires platform-specific functionality or performance optimizations.

This approach gives you the flexibility to fine-tune the SDK's behavior to meet the unique needs of each platform. However, the available options are limited to what the KMP SDK has implemented. If you need to use the respective platform's options directly, you should use the native platform options approach.

commonMain/AppSetup.kt
Copied
import io.sentry.kotlin.multiplatform.Context

expect fun initializeSentry()

androidMain/AppSetup.kt
Copied
import io.sentry.kotlin.multiplatform.Sentry
import io.sentry.kotlin.multiplatform.Context

actual fun initializeSentry() {
  Sentry.init {
    it.dsn = "https://examplePublicKey@o0.ingest.sentry.io/0"
    // Add Android-specific configuration here
  }
}

iosMain/AppSetup.kt
Copied
import io.sentry.kotlin.multiplatform.Sentry
import io.sentry.kotlin.multiplatform.Context

actual fun initializeSentry() {
  Sentry.init {
    it.dsn = "https://examplePublicKey@o0.ingest.sentry.io/0"
    // Add iOS-specific configuration here
  }
}

It's also possible to mix the initialization strategies by creating intermediate sourceSets that target specific platforms. This allows you to use a shared initializer for some platforms, while utilizing platform-specific initializers for others.

For example, you may choose to use a shared initializer for Android and iOS platforms, while using a platform-specific initializer for the watchOS and tvOS platforms. This approach provides a balance between consistency and customization.

Help improve this content
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").