---
title: CAS.AI plugin for Kotlin Multiplatform
---

Integrating CAS SDK into an app is the first step toward displaying ads and earning revenue.
Once you've integrated and initialized the SDK, you can choose an ad format and follow the steps to implement it.

The plugin exposes a single `expect` API from `commonMain`, backed by the native CAS.AI SDK on each platform.
Banner and Native ads are also available as Compose Multiplatform composables, so the whole integration can live in shared code.

## Prerequisites
Make sure that your app's build files use the following values:
- Use Kotlin `{{ min.kotlin }}` or higher
- Use Compose Multiplatform `{{ min.compose }}` or higher, if you use the ad composables
- For Android:
  - Minimum API level `{{ min.api }}` or higher
  - Compile SDK version of `{{ min.targetapi }}` or higher
- For iOS:
  - Use Xcode `{{ min.xcode }}` or higher
  - Minimum Target iOS version `{{ min.ios }}` or higher
  - Supported targets: `iosArm64` and `iosSimulatorArm64`. There is no x86_64 simulator target,
    so a Mac with an Intel processor cannot run the simulator build

## Import CAS.AI Mobile Ads library
Add the CAS.AI Kotlin Multiplatform library to the common source set of your shared module.

```kotlin
// <project>/shared/build.gradle.kts
kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("com.cleveradssolutions:cas-kmp:{{ versions.kmp }}")
        }
    }
}
```

<Card title="Subscribe" icon="github" href="https://github.com/cleveradssolutions/CAS-KMP/subscription">
Subscribe to receive notifications about CAS updates.
</Card>

Now in your common Kotlin code, you can use:
```kotlin
import com.cleveradssolutions.plugin.kmp.*
```

<Info>
The Android artifact declares the CAS.AI Android SDK as `compileOnly`, so the SDK itself and the
mediation adapters are resolved by your application. The platform setup below adds them.
</Info>

## Platform specific setup
To monetize your app using CAS.AI mediation, in addition to importing the library, you need to configure
your Android and iOS projects by using the **CAS Gradle plugin** for Android and the **CAS Swift Package** for iOS.

<Tabs groupId="platform">
<TabItem label="Android" value="android">
The CAS Android SDK provides a Gradle Plugin to simplify and automate certain integration steps.
Our plugin will automatically add mediated network dependencies to your project, which you configure in a `cas { }` block.

Apply `com.cleveradssolutions.gradle-plugin` to the module that holds the Android target, inside the `plugins` block
and after the Android plugin itself.

```kotlin
// <project>/shared/build.gradle.kts
plugins {
    kotlin("multiplatform")
    id("com.android.application") // before CAS plugin
    id("com.cleveradssolutions.gradle-plugin") version "{{ versions.android }}"
}

cas {
    // Plugin configuration
}
```

#### Add Maven repositories
Several ad networks do not publish their Android SDK to Maven Central, so their adapters cannot be resolved
without the network's own repository. The CAS Gradle plugin does not add them for you.

Copy the repositories block from [Add Maven repositories](Android#add-maven-repositories) into the
`dependencyResolutionManagement` of your `settings.gradle.kts`.

<Error>
Without them the Android build fails while resolving dependencies, with a message such as
`Could not find com.mbridge.msdk.oversea:mbridge_android_sdk`, and the same for `com.pangle.global`,
`com.ysocorp` and the other networks that host their own artifacts.
</Error>

<Success>
Make sure to update the CAS Gradle plugin version whenever you update the CAS Kotlin Multiplatform library. The CAS Gradle plugin version matches the version of [the CAS Android SDK](https://github.com/cleveradssolutions/CAS-Android/releases). For detailed setup instructions, visit [the CAS Android repository](Android#integration-options).
</Success>
</TabItem>

<TabItem label="iOS" value="ios">
The CAS iOS SDK is distributed as a **Swift Package**. Add it to the Xcode project that hosts your shared module.

<Steps>
<Step title="Add the package dependency">
In Xcode, select **File ▸ Add Package Dependencies…** and enter the CAS Git repository URL into the
**Search or Enter Package URL** field:
```
https://github.com/cleveradssolutions/CAS-iOS
```
</Step>
<Step title="Specify the version">
Set the **Dependency Rule** to **Up to Next Minor Version** and enter `{{ versions.ios }}`, then click **Add Package**.

Keep this version in step with the CAS Gradle plugin on Android. Both are updated together with the Kotlin
Multiplatform library.
</Step>
<Step title="Choose the library products">
Xcode then asks which library products to add to which target. Check `CleverAdsSolutionsSPM`, which is the
CAS.AI SDK itself, and one `CASMediation*` product per ad network you want to monetize with. The list of
products is in [Choose Mediated Networks](#choose-mediated-networks) below.

Nothing has to be imported or called in code for an adapter to work: each product carries the adapter binary,
and the CAS.AI SDK discovers it at runtime.
</Step>
</Steps>

Alternatively, if your Xcode project consumes a local Swift package of your own, declare the dependency in its
`Package.swift`:
```swift
dependencies: [
    .package(
        url: "https://github.com/cleveradssolutions/CAS-iOS",
        .upToNextMinor(from: "{{ versions.ios }}")
    )
]
```
The products then go into the dependencies of your target, see [Choose Mediated Networks](#choose-mediated-networks).

<Info>
The CAS.AI SDK is also published through CocoaPods. Swift Package Manager is the recommended option for
new projects and is the one these pages document. If your project already uses CocoaPods, follow
[the iOS integration page](iOS) instead.
</Info>

### Deliver the Kotlin framework to Xcode
Your shared module is compiled into an Apple framework that the Xcode project links against. Declare the
framework binary in the shared module:

```kotlin
// <project>/shared/build.gradle.kts
kotlin {
    listOf(iosArm64(), iosSimulatorArm64()).forEach { iosTarget ->
        iosTarget.binaries.framework {
            baseName = "Shared"
            isStatic = true
        }
    }
}
```

Then connect it to Xcode with the direct integration mechanism of the Kotlin Gradle plugin:
1. In your Xcode project, select the application target and open the **Build Phases** tab.
2. Add a **New Run Script Phase** and move it **before** the **Compile Sources** phase.
3. Use the following script, where `shared` is the Gradle path of your shared module:
```shell
cd "$SRCROOT/.."
./gradlew :shared:embedAndSignAppleFrameworkForXcode
```
4. In **Build Settings**, add the framework output directory to **Framework Search Paths**:
```
$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)
```
5. Build the project once, then add `Shared.framework` under **Frameworks, Libraries, and Embedded Content** of the application target.

<Info>
See [Integration with the Xcode build](https://www.jetbrains.com/help/kotlin-multiplatform-dev/multiplatform-direct-integration.html) in the Kotlin Multiplatform documentation for the full description of this mechanism.
</Info>

### Configure the iOS project
The Xcode project needs a set of additional settings that CAS.AI maintains for you in a Ruby script, so that
they stay correct as the mediated networks change. The script configures:

- `SKAdNetworkItems` and the AdAttributionKit identifiers of every mediated network, in `Info.plist`
- `NSUserTrackingUsageDescription`, the App Tracking Transparency prompt text
- `GADApplicationIdentifier` and the Google delay app measurement flag
- App Transport Security
- `$(inherited)` and `-ObjC` in the **Other Linker Flags** of the project

<Error>
The adapters are discovered by class name at runtime. Without the `-ObjC` flag the linker strips their
Objective-C classes: the project builds and the SDK initializes, but every mediated network stays
unavailable and ads are never filled.
</Error>

<Steps>
<Step title="Download the script">

Download [casconfig.rb](https://github.com/cleveradssolutions/CAS-iOS/releases/download/{{ versions.iosconfig }}/casconfig.rb) and place it in the `iosApp` directory, next to the app `.xcodeproj`.

</Step>
<Step title="Run it with your CAS ID">
```shell
cd iosApp
ruby casconfig.rb <CAS ID>
```

The script can also live anywhere else, as long as you point it at the project:
```shell
ruby /path/to/casconfig.rb <CAS ID> --project=/path/to/iosApp.xcodeproj
```

Run `ruby casconfig.rb --help` to see the rest of its options.
</Step>
</Steps>

<Success>
Repeat the script before every update of the app to make sure you are using up-to-date configurations. For
details on what each setting does, and how to apply them by hand, see
[Manually configure project](iOS/Manually-configure-project).
</Success>

<AccordionGroup>
<Accordion title="What is CAS ID in iOS?">

In most cases, a CASID is the same as your app store ID.
You can find an app store ID in the URL of your app’s Apple App Store URL. For example, the URL is `apps.apple.com/us/app/id123456789` then app store ID is `123456789`.

If you haven't created an CAS account and registered an app yet, now's a great time to do so at https://cas.ai
If you just want to experiment or test the SDK, you can skip the configuration your project.

</Accordion>
</AccordionGroup>

</TabItem>
</Tabs>

## Choose Mediated Networks
<Warning>
CAS.AI is a mediation SDK with no built-in live ad inventory. At least one ad network adapter or solution must be integrated before publishing to display ads and generate revenue.
</Warning>

Choose an integration path based on your app's target audience. If you're unsure which solution best fits your application, please contact your account manager.

<Info>
During development, you can test ad formats using [Test Ads](KMP/Enabling-test-ads) without adding any ad network SDKs.
</Info>

Check the details of the ad network adapters supported by CAS.AI Mediation in the [Android repository](https://github.com/cleveradssolutions/CAS-Android/blob/master/Adapters/README.md) and [iOS repository](https://github.com/cleveradssolutions/CAS-iOS/blob/master/Adapters/README.md) tables.

### Android
The CAS Gradle plugin offers curated solutions that CAS.AI keeps up to date.

<AccordionGroup>
<Accordion defaultOpen title="Optimal Ads Solution">

Recommended for **most applications** targeting a **general or mixed audience**. Includes a broad set of stable, high-performance networks.

```kotlin
// <project>/shared/build.gradle.kts
cas {
    includeOptimalAds = true
}
```

</Accordion>

<Accordion title="Families Ads Solution">

Required for applications **directed exclusively at children**, in accordance with the [Google Play Families Policy](https://support.google.com/googleplay/android-developer/answer/12918983?hl=en) and fully compatible with the [Children’s Online Privacy Protection Act (COPPA)](https://www.ftc.gov/tips-advice/business-center/privacy-and-security/children%27s-privacy).

```kotlin
// <project>/shared/build.gradle.kts
cas {
    includeFamiliesAds = true
}
```

</Accordion>

<Accordion title="VPN Compliant Ads Solutions">

Designed specifically for applications that provide VPN or proxy services. This solution includes partner networks that comply with VPN-related traffic policies and restrictions.

```kotlin
// <project>/shared/build.gradle.kts
cas {
    includeVPNCompliantAds = true
}
```

</Accordion>

<Accordion title="Choice mediation adapters">

Advanced publishers familiar with ad network integrations can configure their own set of adapters.

```kotlin
// <project>/shared/build.gradle.kts
cas {
    adapters {
        googleAds = true
        unityAds = true
        appLovin = true
    }
}
```

For detailed instructions on how to integrate specific adapters into your app, refer to the [Android page](Android/Mediated-Networks).

</Accordion>
</AccordionGroup>

### iOS
The Swift Package exposes one library product per mediation network. Adding a network is an Xcode step, not a
code change: the product carries the adapter binary and the CAS.AI SDK picks it up at runtime.

<Tabs groupId="iosnetworks">
<TabItem label="In Xcode" value="xcode">
If you are adding the package for the first time, tick the products in the dialog that Xcode shows after
**Add Package**.

To change the selection later:
1. Select your project in the Project navigator, then select the application target.
2. Open the **General** tab and find **Frameworks, Libraries, and Embedded Content**.
3. Click **+**, pick the `CASMediation*` products you want from the `CleverAdsSolutions` package, and confirm.
4. Remove a product from the same list to drop a network.

Re-run the [configuration script](#configure-the-ios-project) after changing the selection. It refreshes the
`SKAdNetworkItems` of the networks you added and keeps the `-ObjC` linker flag in place.
</TabItem>
<TabItem label="In Package.swift" value="manifest">
If your Xcode project consumes a local Swift package of your own, list the products as dependencies of your target:

```swift
.target(
    name: "YourApp",
    dependencies: [
        .product(name: "CleverAdsSolutionsSPM", package: "CleverAdsSolutions"),
        .product(name: "CASMediationGoogleAds", package: "CleverAdsSolutions"),
        .product(name: "CASMediationUnityAds", package: "CleverAdsSolutions"),
    ],
    linkerSettings: [
        .unsafeFlags(["-ObjC"])
    ]
)
```
</TabItem>
</Tabs>

Add the products of the networks you need to your application target, alongside `CleverAdsSolutionsSPM`.

The [adapters table of the CAS iOS repository](https://github.com/cleveradssolutions/CAS-iOS/blob/master/Adapters/README.md)
lists every network and is kept up to date with each release. Three of its columns matter when you pick yours:

- **SPM** — whether the adapter is distributed through Swift Package Manager. A few are not, because of
  limitations of the ad frameworks themselves. If you need one of those, use the
  [CocoaPods integration](iOS#cocoapods) instead.
- **Optimal**, **Families**, **VPN** — which curated CAS.AI solution the network belongs to. Take the rows
  ticked in the column of the solution that fits your audience, the same set that `includeOptimalAds` and its
  siblings give you on Android.

The library product of a network is its name in the table prefixed with `CASMediation`, for example
`CASMediationGoogleAds` for the `GoogleAds` row. The one exception is `CASExchange`, whose product is
`CASMediationExchange`. Xcode lists the exact products when you add the package, so you never have to guess.

<Info>
Curated `Optimal`, `Families` and `VPNCompliant` products do not exist in the Swift Package yet, so the
networks of a solution are added one by one for now. They are planned for a future update of the package.
</Info>

<Warning>
The Android and iOS network sets are configured separately and are expected to differ. Not every network
ships an adapter for both platforms, store policies for child-directed apps do not approve the same networks,
and individual iOS adapters raise the minimum deployment target. Pick the networks per platform rather than
mirroring one list onto the other.
</Warning>

## Advertising Identifier
CAS Mediation uses the [Google Advertising ID](https://support.google.com/googleplay/android-developer/answer/6048248?hl=en) and [Apple Identifier for Advertisers (IDFA)](https://developer.apple.com/documentation/adsupport) to deliver personalized and more relevant ads to each user.
To enable the use of the Advertising ID in your app, you need to complete the following setup steps.

<AccordionGroup>
<Accordion title="Android Google Advertising ID">
CAS Mediation allows you to easily enable or disable the use of the Advertising ID, depending on your app’s privacy requirements.

```kotlin
// <project>/shared/build.gradle.kts
cas {
    useAdvertisingId = true
}
```

An application must not use an advertising identifier if **at least one** of the following conditions is true:
- The app’s target audience includes **only children**, as defined in the [Families Policy](https://support.google.com/googleplay/android-developer/answer/9893335?sjid=10683822576513227860-EU).
- The app is being built for **devices that do not use Google Play Services** (e.g. Amazon or Huawei devices).

</Accordion>

<Accordion title="iOS User Tracking Usage description">

To use the App Tracking Transparency authorization request for accessing the IDFA, update the `iosApp/Info.plist` to add the [NSUserTrackingUsageDescription](https://developer.apple.com/documentation/bundleresources/information_property_list/nsusertrackingusagedescription) key (Name in Xcode Property List Editor: `Privacy - Tracking Usage Description`) with a custom message describing your usage. Below is an example description text:
```xml
<key>NSUserTrackingUsageDescription</key>
<string>Your data will remain confidential and will only be used to provide you a better and personalised ad experience</string>
```

- Your data will remain confidential and will only be used to provide you a better and personalised ad experience
- Your data will be used to provide you a better and personalised ad experience
- Your data will be used to create a customized experience tailored to your interests
- Allowing tracking will enable more personalized ads for you
- We try to show ads for apps and products that will be most interesting to you based on the apps you use
- This identifier will be used to deliver personalized ads to you
- This only uses device info for more interesting and relevant ads

</Accordion>
<Accordion title="iOS Localizing Usage description (optional)">

To optimize performance and to improve the user experience, you can localize the `NSUserTrackingUsageDescription` string. Please follow the [Documentation > Xcode > Localization](https://developer.apple.com/documentation/xcode/localization) instructions to learn how to localize your app.
The table below gives you a variety of localizations that you can use at your discretion.

| Locale          | Description                            |
|-----------------|----------------------------------------------------------------------------|
| English (en)    | Your data will remain confidential and will only be used to provide you a better and personalised ad experience                               |
| German (de)     | Ihre Daten bleiben vertraulich und werden nur dazu verwendet, Ihnen ein besseres und personalisiertes Werbeerlebnis zu bieten                 |
| French (fr)     | Vos données resteront confidentielles et seront utilisées uniquement pour vous offrir une expérience publicitaire meilleure et personnalisée  |
| Spanish (es)    | Sus datos permanecerán confidenciales y solo se utilizarán para brindarle una experiencia publicitaria mejor y personalizada                  |
| Ukrainian (uk)  | Ваші дані залишатимуться конфіденційними та використовуватимуться лише для надання вам кращої та персоналізованої реклами                     |
| Russian (ru)    | Ваши данные останутся конфиденциальными и будут использоваться только для предоставления вам более качественной и персонализированной рекламы |
| Portuguese (pt) | Seus dados permanecerão confidenciais e serão usados apenas para lhe proporcionar uma experiência publicitária melhor e personalizada         |
| Japanese (ja)   | お客様のデータは機密として保持され、より優れたパーソナライズされた広告エクスペリエンスを提供するためにのみ使用されます |

</Accordion>
</AccordionGroup>
