A Kotlin Multiplatform library to rapidly get Google AdMob running on Android and iOS
Basic-Ads uses the existing Android and iOS Google AdMob libraries to display ads as Composables.
A full walkthrough is available on Medium,
and there's also an easy-start template.
In case you need it, here's the Basic-Ads API Documentation
For Android, complete the steps in AdMob's instructions:
For iOS, complete the steps in AdMob's instructions:
-
[For GDPR Compliance Only] Import the User Messaging Platform SDK
Note
For Xcode 13+, you can update your Custom iOS Target Properties.
Important
Don't forget to check the list of transitive dependencies and versions to ensure compatibility.
Add your dependencies from Maven
# in your 'libs.versions.toml' file
[versions]
kotlin = "+" # gets the latest version
compose = "+" # gets the latest version
basic = "+" # gets the latest version
google-play-services-ads = "+" # you did this during the preparation step
android-ump = "+" # you did this during the preparation step
[libraries]
basic-ads = { module = "app.lexilabs.basic:basic-ads", version.ref = "basic"}
google-play-services-ads = { module = "com.google.android.gms:play-services-ads", version.ref = "google-play-services-ads"}
android-ump = { module = "com.google.android.ump:user-messaging-platform", version.ref = "android-ump" }
[plugins] # make sure you're using the JetBrains plugin to import your composables
jetbrainsCompose = { id = "org.jetbrains.compose", version.ref = "compose" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }then include the library in your gradle build
// in your 'composeApp/build.gradle.kts' file
plugins {
alias(libs.plugins.jetbrainsCompose)
alias(libs.plugins.compose.compiler)
}
sourceSets {
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
implementation(libs.lexilabs.basic.ads)
}
androidMain.dependencies {
implementation(libs.google.play.services.ads)
implementation(libs.android.ump)
}
}Call BasicAds.initialize in your commonMain before building ads.
Note
You only need to initialize Basic-Ads in your commonMain. You do not need to initialize within each platform.
// in your 'composeApp/src/commonMain/App.kt' file
@OptIn(DependsOnGoogleMobileAds::class)
@Composable
fun App() {
// You'll need to access your platform-specific context (Android) or null (iOS) to pass as an `Any?` argument
BasicAds.initialize(activity)
}You can build a BannerAd via a Composable function:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
@Composable
fun AdScreen() {
BannerAd() // Results in a Test Banner Ad being created
}If you want to preload your BannerAds, there's a way to do that too:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd(activity)
// Display the Ad as soon as it's available
BannerAd(bannerAd)You can also check the AdState before doing something:
// Load the Ad within your Composable
val bannerAd by rememberBannerAd(activity)
// Determine to show or hide the Ad
var showBannerAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showBannerAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = bannerAd.state == AdState.READY
) { Text("Show Banner Ad") } // label for the button
// Checks for button click
if (showBannerAd){
// Shows Composable Ad
BannerAd(bannerAd)
}You can also build other Ad types, but you'll need to pass your Android Activity Context when you initialize.
// in your 'composeApp/src/commonMain/AdScreen.kt' file
// You'll need to access your platform-specific Activity (Android) or null (iOS) to pass as an `Any?` argument
InterstitialAd(activity)
RewardedAd(activity, onRewardEarned = {/** do something here **/})
RewardedInterstitialAd(activity, onRewardEarned = {/** do something here **/}) // currently a Google Beta featureIf you want to preload your ads, there's a way to do that too:
// Load the Ad within your Composable
val rewardedAd by rememberRewardedAd(activity)
// Display the Ad as soon as it's available
RewardedAd(
ad = rewardedAd,
onRewardEarned = { rewardItem ->
/** do something here with the rewardItem (if it exists) **/
}
)You can also check the AdState before doing something:
// Load the Ad within your Composable
val interstitialAd by rememberInterstitialAd(activity)
// Determine to show or hide the Ad
var showInterstitialAd by remember { mutableStateOf(false) }
// Composable Button with callbacks
Button(
onClick = { showInterstitialAd = true }, // Shows the ad on click
/** Checks AdState and disables the button if ad isn't ready **/
enabled = interstitialAd.state == AdState.READY
) { Text("Show Interstitial Ad") } // label for the button
// Checks for button click
if (showInterstitialAd){
// Shows Composable Ad
InterstitialAd(interstitialAd)
}Tip
Consent Popups are typically only required for Californian or International audiences. GDPR is a very in-depth topic, so please begin by reading about what GDPR is and how AdMob complies with GDPR requirements.
You can use the Consent features of Basic Ads with Composables too:
// in your 'composeApp/src/commonMain/AdScreen.kt' file
// You'll need to access your platform-specific Activity (Android) or null (iOS) to pass as an `Any?` argument
val consent by rememberConsent(activity)
// Create a ConsentPopup (if available in your region)
ConsentPopup(consent)
// Check if the user can see ads
if (consent.canRequestAds) {
// Call your ads here
InterstitialAd()
}Caution
Advanced Users Only
- Find a large cup. It must exist in the real world.
- Fill said cup to the brim with some sort of caffeinated beverage.
- Click
File>Invalidate Caches..., check all boxes and hitinvalidate and restart - Click
Syncfor gradle if banner exists. Ignore the flood of warning lights and klaxons. - Click
Build>Clean Cache. Ignore the plethora of errors - Once complete, click
Build>Rebuild Project. NOTE: Despite religious preference, prayer is encouraged.