AdMob Integration in Compose Multiplatform
Hello friends, in this article I will show you how to implement banner and interstitial(fullscreen) ad in compose multiplatform.

First of all you need to know how is the Kotlin Multiplatform architecture, what actual expect functions do, cocoapods installation and AdMob ad creation. If you don’t know please check this links:
https://guides.cocoapods.org/using/getting-started.html
https://kotlinlang.org/docs/multiplatform-get-started.html
https://admob.google.com/home/
Scenerio:
We have a App function which starts the application and it has 3 parameter. First one is for banner ad, second one is for loading fullscreen ad and last one is for showing fullscreen ad. You can invoke this parameters in anywhere like showFullScreenAd to a button click, createBannerAd to top of the Box etc.
fun App(
createBannerAd: @Composable () -> Unit,
loadFullScreenAd: () -> Unit,
showFullScreenAd: () -> Unit
) {
MaterialTheme {
LaunchedEffect(Unit) {
loadFullScreenAd.invoke()
}
Box(Modifier.fillMaxSize()) {
createBannerAd.invoke()
Button(
modifier = Modifier.align(Alignment.Center),
onClick = {
showFullScreenAd.invoke()
},
content = {
Text("Click me for fullscreen ad")
}
)
}
}
}
In each platform we will create native calls with this 3 parameters.
Android Implementation:
We will implement for each platform(Android/IOS). Let’s implement for Android first:
- Add play-services-ads dependency to libs.versions.toml:
google-playServices-ads = { group = "com.google.android.gms", name = "play-services-ads", version.ref = "google-play-services" }
- Implement in build.gradle.kts:
sourceSets {
androidMain.dependencies {
implementation(libs.google.playServices)
}
}
- In AndroidManifes.xml, define your application id:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="your_application_id_from_admob"/>
</application>
</manifest>
- In MainActivity.kt, App function call for Android will look like:
class MainActivity : ComponentActivity() {
private var interstitialAd: InterstitialAd? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
CoroutineScope(Dispatchers.IO).launch {
MobileAds.initialize(this@MainActivity)
}
App(
createBannerAd = {
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = { context ->
AdView(context).apply {
setAdSize(AdSize.FULL_BANNER)
adUnitId = "your_banner_add_unit_id_from_admob"
loadAd(AdRequest.Builder().build())
}
}
)
},
loadFullScreenAd = {
InterstitialAd.load(
this@MainActivity,
"your_interstitial_add_unit_id_from_admob",
AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(p0: InterstitialAd) {
interstitialAd = p0
}
override fun onAdFailedToLoad(p0: LoadAdError) {
interstitialAd = null
}
}
)
},
showFullScreenAd = {
interstitialAd?.show(this@MainActivity)
}
)
}
}
IOS Implementation:
We will use cocoapods for native ios. Because of that we have to initialize pod from terminal. cd your iosApp folder in terminal and enter this command:
pod init
If you can see Podfile in iosApp folder, the initialization completed successfully.
- Let’s add google ads dependency to Podfile:
platform :ios, '12.0'
target 'iosApp' do
use_frameworks!
pod 'Google-Mobile-Ads-SDK'
end
- Install pods in terminal
pod install --repo-update
- Define application id from AdMob in Info.plist:
<dict>
<key>GADApplicationIdentifier</key>
<string>your_application_id_from_admob</string>
</dict>
- Create AppDelegate.swift class for initializing AdMob:
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil)
return true
}
}
- Use AppDelegate in iOSApp.swift:
@main
struct iOSApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
- Create BannerAdView.swift for banner view:
struct BannerAdView: UIViewRepresentable {
let adUnitID: String
func makeUIView(context: Context) -> GADBannerView {
let bannerView = GADBannerView()
bannerView.adUnitID = adUnitID
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene
if let rootViewController = windowScene?.windows.first?.rootViewController {
bannerView.rootViewController = rootViewController
}
bannerView.load(GADRequest())
return bannerView
}
func updateUIView(_ uiView: GADBannerView, context: Context) {
}
}
- Create Coordinator NSObject for fullscreen ad:
class Coordinator: NSObject {
var interstitialAd: GADInterstitialAd?
func loadInterstitialAd() async {
do {
self.interstitialAd = try await GADInterstitialAd.load(
withAdUnitID: "your_intrestitial_ad_unit_id_from_admob",
request: GADRequest()
)
} catch {
print("Failed to load interstitial ad: \(error)")
}
}
func showInterstitialAd() {
if let interstitialAd = interstitialAd {
interstitialAd.present(fromRootViewController: nil)
} else {
print("Interstitial ad is not ready")
}
}
}
- The implementation in ComposeView:
struct ComposeView: UIViewControllerRepresentable {
func makeCoordinator() -> Coordinator {
Coordinator()
}
func makeUIViewController(context: Context) -> UIViewController {
MainViewControllerKt.MainViewController(
createBannerAd: { () -> UIViewController in
let adBannerView = VStack {
AdBannerView(adUnitID: "banner_unit_id_from_admob")
}
return UIHostingController(rootView: adBannerView)
},
loadFullScreenAd: {
Task { [weak coordinator = context.coordinator] in
await coordinator?.loadInterstitialAd()
}
},
showFullScreenAd: {
context.coordinator.showInterstitialAd()
}
)
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}
- And finally our MainViewController will be like this:
@OptIn(ExperimentalForeignApi::class)
fun MainViewController(
createBannerAd: () -> UIViewController,
loadFullScreenAd: () -> Unit,
showFullScreenAd: () -> Unit
) = ComposeUIViewController {
val swiftUiBannerAd = @Composable {
UIKitViewController(
// If you don't set 50.dp height it occurs error
modifier = Modifier.fillMaxWidth()
.height(50.dp),
factory = createBannerAd
)
}
App(
createBannerAd = swiftUiBannerAd,
loadFullScreenAd = loadFullScreenAd,
showFullScreenAd = showFullScreenAd
)
}
NOTE: If you got “no such module GoogleMobileAds” error when you run for ios. Open iosApp folder in Xcode and follow the steps in this link:
https://stackoverflow.com/questions/44004410/no-such-module-googlemobileads-in-swift-3
Final look on Android:

Final look on iOS:

Thanks for reading :)
If you have any question you can reach me via:
https://x.com/emirhan_emmez
https://www.linkedin.com/in/emirhanemmez/
Stackademic 🎓
Thank you for reading until the end. Before you go:
- Please consider clapping and following the writer! 👏
- Follow us X | LinkedIn | YouTube | Discord
- Visit our other platforms: In Plain English | CoFeed | Differ
- More content at Stackademic.com