Setup the widget
This page walks through wiring the StorifyMe KMP SDK into a fresh KMP project and rendering a widget on each platform.
1. Register the Maven repository
Add the StorifyMe Maven repository to your root settings.gradle.kts so every module can resolve KMP artifacts.
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url = uri("https://sdk.storifyme.com/android") }
maven { url = uri("https://sdk.storifyme.com/kotlin-multiplatform") }
}
}
For development builds, swap in sdk.dev.storifyme.com.
2. Add the dependency
Add the KMP SDK to your shared module's commonMain:
kotlin {
androidTarget()
listOf(iosX64(), iosArm64(), iosSimulatorArm64()).forEach { it.binaries.framework { baseName = "shared" } }
sourceSets {
commonMain.dependencies {
implementation("com.storifyme.sdk:kotlin-multiplatform-sdk:<latest_version>")
}
}
}
3. Apply the iOS linker script
The KMP SDK depends on two iOS frameworks (StorifyMe.xcframework and StorifyMeKMPBridge.xcframework). Apply the published Gradle script that downloads and links them for you — no manual Xcode wiring, no CocoaPods.
apply(
from = "https://sdk.storifyme.com/kotlin-multiplatform/gradle/<latest_version>/storifyme-kmp-ios-linker.gradle.kts"
)
The script:
- Downloads
StorifyMe.xcframework+StorifyMeKMPBridge.xcframeworktobuild/storifyme-kmp/on first run. - Sets up cinterop and linker flags for every iOS target.
- Caches the download — re-runs are no-ops.
4. Initialize the SDK
Initialize once at app launch — same call site on both platforms:
import com.storifyme.kmp.StorifyMe
import com.storifyme.kmp.StorifyMeEnv
import com.storifyme.kmp.StorifyMeInitConfig
fun startStorifyMe() {
StorifyMe.init(StorifyMeInitConfig(
apiKey = "<your api key>",
accountId = "<your account id>",
env = StorifyMeEnv.EU, // or StorifyMeEnv.US — match your StorifyMe account region.
))
}
Call startStorifyMe() from your Android Application.onCreate() and your iOS @main App.init().
5. Mount the widget
The widget factory lives in androidMain / iosMain because mounting needs a platform View / UIView. The Kotlin call shape is the same.
- Android
- iOS
import com.storifyme.kmp.StorifyMe
import com.storifyme.kmp.widget.StorifyMeWidgetFactory
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val widget = StorifyMeWidgetFactory.create(this).apply {
widgetId = 74L
setWidgetListener(object : StorifyMeWidgetListener {
override fun onLoaded(widgetId: Long, experiences: List<StorifyMeExperience>) {
println("Loaded ${experiences.size} experiences")
}
})
}
findViewById<FrameLayout>(R.id.widgetContainer).addView(widget.view)
StorifyMe.whenReady { widget.load() }
}
shared/src/iosMain/.../IosWidget.kt:
@file:OptIn(kotlinx.cinterop.ExperimentalForeignApi::class)
import com.storifyme.kmp.StorifyMe
import com.storifyme.kmp.widget.StorifyMeWidgetFactory
import platform.UIKit.UIView
fun buildWidget(): UIView {
val widget = StorifyMeWidgetFactory.create().apply { widgetId = 74L }
StorifyMe.whenReady { widget.load() }
return widget.view
}
iosApp/.../ContentView.swift (SwiftUI wrapper):
import SwiftUI
import shared
struct WidgetView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView { IosWidgetKt.buildWidget() }
func updateUIView(_ uiView: UIView, context: Context) {}
}
whenReady?On iOS, StorifyMe.init is asynchronous — templates fetch over the network after init returns. Calling widget.load() immediately can race the init and render an empty widget. whenReady { ... } fires the callback as soon as init completes (or immediately if already done). On Android init is synchronous, so the callback fires inline; the same call site works on both platforms.
6. Run the demo
A working demo project lives in kotlin-multiplatform-sdk/consumer-sample/ — clone it as a reference for settings.gradle.kts, build.gradle.kts wiring, and the Android/iOS app shells.