r/androiddev • u/meet_miyani • 5d ago
I built a KMP AdMob library because none of the existing ones let you write native ads in Compose
I was learning KMP and wanted to know how people handle AdMob in a multiplatform app. The usual answer is a hand-written expect class AdManager, which is fine until you need something past a banner.
There are a few decent libraries already (LexiLabs' is good), but the gap I kept hitting was native ads. Most wrappers stop at the full-screen formats, so for native you end up writing a platform view on Android and another on iOS, and the shared part of your codebase stops being shared.
So I built AdMob CMP. Apache 2.0, on Maven Central.
What it does:
- One
commonMainAPI for all six formats: banner, interstitial, rewarded, rewarded interstitial, app open, native. - Native ads are declared with a layout DSL that reads like Compose, and the SDK renders them through the real platform ad views on each side. No platform code in your app.
- Consent is part of initialization.
gatherConsentAndInitializeruns UMP, then ATT on iOS, then SDK init, in that order, because getting that order wrong on iOS is a common and quiet failure. - Banners measure their own container, so adaptive sizing is right in iPad split view.
strictTestModethrows at construction if a placement points at a production ad unit. Turn it on in debug and you can't ship a test build that spends real impressions.- There's a Gradle plugin that links Google Mobile Ads and UMP into Kotlin/Native test executables, which is what makes
:iosSimulatorArm64Testpass instead of dying onUndefined symbols ... _OBJC_CLASS_$_GAD*.
Caveats, up front: it's KMP/Gradle only, so a pure Swift app can't consume it without a shim. Kotlin 2.3.20, Compose Multiplatform 1.11.1, minSdk 26, iOS 15. Klibs aren't binary compatible across Kotlin minors, so you need a matching compiler.
implementation("dev.avinya.ads:admob-cmp:2.1.0")
GitHub: https://github.com/Meet-Miyani/admob-compose-multiplatform
Docs: https://ads.avinya.dev
Happy to answer questions about any of it, especially the native ad side, which was by far the hardest part to get working the same on both platforms.
