# Flutter plug-in integration

> Integrate the LevelPlay SDK into your Flutter application to enable ad mediation and monetization across Android and iOS platforms.

## Prerequisites

* Flutter plug-in is supported from SDK version 7.2.1.2 for Android & iOS.
* Support Flutter 3.0.0+
* Plug-in version 9.3.0 and higher (Android and iOS SDK 9.6.1) has the following build requirements:
  * **Android**: Build your app with Kotlin 2.0 or higher. The Android SDK depends on `kotlin-stdlib` 2.1.x.
  * **iOS**: Build your app with Xcode 26 or higher, with a minimum deployment target of iOS 13.

## Add the LevelPlay Mediation plug-in to your project

### Pub.dev Integration

There are 2 options of adding the LevelPlay Flutter plug-in to your project, using the pub.dev interface.

1. Run the Flutter CLI command

   ```shell
   flutter pub add unity_levelplay_mediation
   ```

2. Update pubspec.yaml file by adding the `unity_levelplay_mediation` definition to your pubspec.yaml file.

   ```yaml
   dependencies:
     flutter:
       sdk: flutter
     unity_levelplay_mediation: ^9.3.0
   ```

3. Add Ad Quality SDK

> **Note:**
>
> As of Flutter plug-in version 3.1.1, Ad Quality is part of the LevelPlay SDK, and the SDK initializes it automatically when you implement LevelPlay. Use the following [Manual integration](#manual-integration) steps for builds without LevelPlay integrated or for Flutter plug-in versions earlier than 3.1.1.

1. **Android**

   ```groovy
   dependencies {
       implementation 'com.unity3d.ads-mediation:adquality-sdk:9.3.1'
   }
   ```

2. **iOS**

   ```ruby
   pod 'IronSourceAdQualitySDK','9.3.1'

   ```

### Manual Integration

[Download the Flutter plug-in](https://pub.dev/packages/unity_levelplay_mediation)

### LevelPlay demo app

The Integration Demo application demonstrates how to integrate ironSource LevelPlay in your app

[Download Flutter Demo Application](https://github.com/ironsource-mobile/Flutter-SDK/tree/master/example)

## Additional settings for iOS

### SKAdNetwork support

To enable the display of ironSource network ads while using SDK 7+, make sure to include the ironSource ad network ID in your app property list file (Info.plist).

1. Select **Info.plist** in the Project navigator in Xcode.
2. Select the **Add button (+)** beside a key in the property list editor and press **Return**.
3. Type the key name **SKAdNetworkItems**.
4. In the **Type** column of the dialog, select **Array**.
5. Create a dictionary item and corresponding single sting item.
6. Enter Key name **SKAdNetworkIdentifier,** and the key value:

   ```xml
   su67r6k2v3.skadnetwork
   ```

   You can also add `SKAdNetworkIdentifier` to your Info.plist with the following code:

```xml
<key>SKAdNetworkItems</key>
<array>
   <dict>
      <key>SKAdNetworkIdentifier</key>
      <string>su67r6k2v3.skadnetwork</string>
   </dict>
</array>
```

Use ironSource [SKAdNetwork IDs Manager](/grow/levelplay/sdk/flutter/skadnetwork-id-manager.md) to create code snippet to support ironSource network and mediated network IDs.

For more information on editing the property list, refer to the [Xcode documentation](https://help.apple.com/xcode/mac/current/#/dev3f399a2a6).

### Universal SKAN Reporting

To receive copies of winning install-validation postbacks from all of the demand sources for your advertised app, add the [NSAdvertisingAttributionReportEndpoint](https://developer.apple.com/documentation/bundleresources/information_property_list/nsadvertisingattributionreportendpoint) key in your app's Info.plist.

1. Select Info.plist in the Project navigator in Xcode
2. Select the Add button (+) beside a key in the property list editor and press Return
3. Type the key name [NSAdvertisingAttributionReportEndpoint](https://developer.apple.com/documentation/bundleresources/information_property_list/nsadvertisingattributionreportendpoint)
4. Choose String from the pop-up menu in the Type column
5. Type the URL: `https://postbacks-is.com/`

### App transport security settings

To ensure uninterrupted support for ad delivery across all mediation networks, it's important to make the following changes in your `info.plist`:

* Add in a dictionary called `NSAppTransportSecurity`. Make sure you add this dictionary on the **Top Level Key**.
* Inside this dictionary, add a Boolean called `NSAllowsArbitraryLoads` and set it to **YES**.
* Make sure that your info.plist doesn't contain any other exceptions besides `NSAllowsArbitraryLoads`, as this might create a conflict.
* Find more information on ATS in the [Apple documentation](https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW33).

## Additional setup for Android

### Play Services Dependencies

Add Play Services Dependencies to your app level build.gradle as follows:

```groovy
dependencies {
   implementation 'com.google.android.gms:play-services-ads-identifier:18.2.0'
   implementation 'com.google.android.gms:play-services-appset:16.1.0'
}
```

#### Android 12 Support

Apps updating their target API level to 31 (Android 12) will need to declare a Google Play services normal permission in the manifest file as follows:

```xml
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
```

Read more about Google Advertising ID changes [here](https://support.google.com/googleplay/android-developer/answer/6048248).

#### Replace Label on AndroidManifest.xml

To prevent the label-related error on AndroidManifest, do the following:

* Add ‘xmls:tools’ to AndroidManifest.xml of your project
* Add ‘tools:replace=”android:label”’ to the ‘application’ tag

## Initialize LevelPlay SDK

To initialize the LevelPlay SDK, follow these steps:

### LevelPlay SDK 8.6.0 and later

1. Implement callbacks for initialization success and failure.

2. Define the list of ad formats to initialize in the session.

3. Create an init request using `LevelPlayInitRequest.builder`. The builder receives the following parameters:

   * Your appKey (mandatory)
   * User ID (optional: required if you're using server-to-server callbacks or using Ad Quality user journey)

4. Call LevelPlay.init and pass the context and init request.

```java
class MyLevelPlayInitListener implements LevelPlayInitListener {
    @override
    void onInitFailed(LevelPlayInitError error) {
	      // Provided when init is failed
    }
    @override
    void onInitSuccess(LevelPlayConfiguration configuration) {
	      // Provided when init is successfully executed
    }
}
LevelPlayInitRequest initRequest = LevelPlayInitRequest.builder([APP_KEY])
                .withUserId("userId") // required for server-to-server callbacks or Ad Quality user journey (optional otherwise)
                .build();
LevelPlay.init(initRequest, MyLevelPlayInitListener());
```

### LevelPlay SDK before 8.6.0

1. Implement callbacks for initialization success and failure.
2. Define the list of ad formats that require support from legacy LevelPlay API. This should include REWARDED.
3. Call the LevelPlay.init API using the appKey, ad formats, and user ID if relevant.

Add the user ID as part of the initialization API if you're using server-to-server callbacks to reward your users, or using Ad Quality user journey.

```java
class MyLevelPlayInitListener implements LevelPlayInitListener {
  @override
  void onInitFailed(LevelPlayInitError error) {
	// Provided when init is failed
  }
  @override
  void onInitSuccess(LevelPlayConfiguration configuration) {
	// Provided when init is successfully executed
  }
}
// Init the SDK when implementing the Multiple Ad Units Interstitial and Banner APIs, and Rewarded using legacy APIs  
List<AdFormat> legacyAdFormats = [AdFormat.REWARDED];
LevelPlayInitRequest initRequest = LevelPlayInitRequest.builder([APP_KEY])
                .withLegacyAdFormats(legacyAdFormats)
                .withUserId("userId") // required for server-to-server callbacks or Ad Quality user journey (optional otherwise)
                .build();
LevelPlay.init(initRequest, MyLevelPlayInitListener());
```

### LevelPlay Init Listeners

* `onInitSuccess`: Triggered when the init completes successfully, and ads can be loaded.
* `onInitFailed`: The configuration wasn't received successfully, and ads can't be loaded. The recommended best practice is to try and init the LevelPlay SDK later.

Consider the following best practices:

* All APIs called before the init API were not changed and should have remained as is, in terms of functionality and syntax. This includes [advanced settings](/grow/levelplay/sdk/unity/additional-settings.md), [regulations settings](/grow/levelplay/sdk/unity/regulation-advanced-settings.md) or other APIs related to specific ad format
* If initialization fails, you can try and initialize the SDK again. Only after a successful initialization process will you be able to load ads.

## Verify your integration

Use the LevelPlay integration test suite to test your app's integration, verify platform setup, and review ads related to your configured networks.

To enable the test suite in your app, call the setMetaData API before setting the init:

```java
LevelPlay.setMetaData({'is_test_suite': ['enable']});
```

After mediation init is completed successfully, launch the test suite by calling the following method (Application Context is required):

```java
LevelPlay.launchTestSuite();
```

For more details and an implementation example of the LevelPlay integration test suite navigate to this [article](/grow/levelplay/sdk/flutter/integration-test-suite.md).

### Adapters Debug

Call the following API to enable debug logs of mediated network adapters & SDKs:

```java
LevelPlay.setAdaptersDebug(true);
```

### For Proguard Users Only

If you are using ProGuard with the LevelPlay SDK, you must add the following code to your ProGuard file (Android Studio: proguard-rules.pro or Eclipse: proguard-project.txt):

```java
-keepclassmembers class com.ironsource.sdk.controller.IronSourceWebView$JSInterface {
    public *;
}
-keepclassmembers class * implements android.os.Parcelable {
    public static final android.os.Parcelable$Creator *;
}
-keep public class com.google.android.gms.ads.** {
   public *;
}
-keep class com.ironsource.adapters.** { *;
}
-keep class com.ironsource.unity.androidbridge.** { *;
}
-dontwarn com.ironsource.mediationsdk.**
-dontwarn com.ironsource.adapters.**
-keepattributes JavascriptInterface
-keepclassmembers class * {
    @android.webkit.JavascriptInterface <methods>;
}
```

## Next steps

1. Follow our integration guides to implement ad formats
   * [Rewarded Video](/grow/levelplay/sdk/flutter/rewarded-ads-integration.md)
   * [Interstitial](/grow/levelplay/sdk/flutter/interstitial-integration.md)
   * [Banner](/grow/levelplay/sdk/flutter/banner-integration.md)
   * [Native Ads](/grow/levelplay/sdk/flutter/native-ads-integration.md)
2. Integrate our Rewarded Video, Interstitial or Banner Ads in your app and follow our [Mediation articles](/grow/levelplay/sdk/flutter/mediation-networks.md).
3. Verify your integration with our [Integration Test Suite](/grow/levelplay/sdk/flutter/integration-test-suite.md).
