> ## Documentation Index
> Fetch the complete documentation index at: https://docs.adrop.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Splash Ads

> Learn how to implement splash ads in your iOS app.

## Overview

Splash ads are displayed on the splash screen when the app launches. The ad appears alongside your app logo, providing a natural user experience.

### Features

* Natural ad exposure at app launch
* Maintains brand image with app logo
* Fixed size of 360px x 270px
* Supports image ads

<Note>
  Use the test unit ID in development: `PUBLIC_TEST_UNIT_ID_SPLASH`
</Note>

***

## Caching Behavior

Splash ads are prefetched and cached on the device so the creative can appear instantly at launch, before any network request completes. On the next launch the cached creative is shown first, and a fresh ad request runs in the background to refresh the cache for subsequent launches.

<Warning>
  Because of this prefetch model, a creative that is **paused** in Ad Control Console may still be shown from the device cache until the next refresh cycle completes on each user's device. Plan creative pauses and replacements with a buffer for the cache to roll over across the install base.
</Warning>

***

## Ad Size

Splash ads use a fixed size:

* **Size**: 360px x 270px (width x height)
* The ad is displayed at the bottom of the screen, with the app logo placed at the top

***

## Implementation Methods

Splash ads can be implemented in three ways depending on your app's requirements:

1. **Using AdropSplashAdViewController** - The simplest method
2. **Using AdropSplashAdView** - Custom splash screen composition
3. **SwiftUI Implementation** - For SwiftUI apps

***

## Method 1: Using AdropSplashAdViewController

The simplest implementation method. `AdropSplashAdViewController` automatically manages the splash screen.

### UIKit Implementation

```swift theme={null}
import AdropAds

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        // Initialize Adrop SDK
        Adrop.initialize(production: false)

        return true
    }
}
```

### Displaying Splash Ad in SceneDelegate

<CodeGroup>
  ```swift Swift theme={null}
  import UIKit
  import AdropAds

  class SceneDelegate: UIResponder, UIWindowSceneDelegate {
      var window: UIWindow?

      func scene(
          _ scene: UIScene,
          willConnectTo session: UISceneSession,
          options connectionOptions: UIScene.ConnectionOptions
      ) {
          guard let windowScene = (scene as? UIWindowScene) else { return }

          // Set up window
          window = UIWindow(windowScene: windowScene)

          // Create splash ad view controller
          let splashViewController = AdropSplashAdViewController(
              unitId: "YOUR_SPLASH_UNIT_ID"
          )
          splashViewController.logoImage = UIImage(named: "app_logo")  // App logo image
          splashViewController.delegate = self

          // Set main view controller
          splashViewController.mainViewController = MainViewController()

          // Set display duration (deprecated — set in console instead, default is 1 second)
          splashViewController.displayDuration = 3.0

          // Set splash screen as root
          window?.rootViewController = splashViewController
          window?.makeKeyAndVisible()
      }
  }
  ```

  ```objc Objective-C theme={null}
  @import AdropAds;

  @interface SceneDelegate () <AdropSplashAdDelegate>
  @property (nonatomic, strong) UIWindow *window;
  @end

  @implementation SceneDelegate

  - (void)scene:(UIScene *)scene
      willConnectToSession:(UISceneSession *)session
               options:(UISceneConnectionOptions *)connectionOptions {

      UIWindowScene *windowScene = (UIWindowScene *)scene;
      if (!windowScene) return;

      // Set up window
      self.window = [[UIWindow alloc] initWithWindowScene:windowScene];

      // Create splash ad view controller
      AdropSplashAdViewController *splashViewController =
          [[AdropSplashAdViewController alloc] initWithUnitId:@"YOUR_SPLASH_UNIT_ID"];
      splashViewController.logoImage = [UIImage imageNamed:@"app_logo"];
      splashViewController.delegate = self;

      // Set main view controller
      splashViewController.mainViewController = [[MainViewController alloc] init];

      // Set display duration (deprecated — set in console instead, default is 1 second)
      splashViewController.displayDuration = 3.0;

      // Set splash screen as root
      self.window.rootViewController = splashViewController;
      [self.window makeKeyAndVisible];
  }

  @end
  ```
</CodeGroup>

### Initialization Parameters

| Parameter          | Type           | Description                                  |
| ------------------ | -------------- | -------------------------------------------- |
| `unitId`           | `String`       | Unit ID created in the Ad Control console    |
| `adRequestTimeout` | `TimeInterval` | Ad request timeout (seconds). Default is 1.0 |

### Properties

| Property             | Type                | Description                                                                         |
| -------------------- | ------------------- | ----------------------------------------------------------------------------------- |
| `logoImage`          | `UIImage?`          | App logo image (set as property, not init parameter). Displayed without logo if nil |
| `mainViewController` | `UIViewController?` | Main view controller to transition to after ad closes                               |
| `backgroundColor`    | `UIColor?`          | Splash screen background color. Uses systemBackground if nil                        |
| `displayDuration`    | `TimeInterval`      | Ad display duration (seconds). Default is 1.0. Deprecated — set in console instead  |

### Delegate Implementation

<CodeGroup>
  ```swift Swift theme={null}
  // MARK: - AdropSplashAdDelegate
  extension SceneDelegate: AdropSplashAdDelegate {
      // Splash ad closed
      func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
          print("Splash ad closed - Impressed: \(impressed)")

          // Transition to main screen
          let mainViewController = MainViewController()
          window?.rootViewController = mainViewController
      }

      // Ad received successfully (optional)
      func onAdReceived(_ ad: AdropSplashAd) {
          print("Splash ad received successfully")
      }

      // Ad failed to receive (optional)
      func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
          print("Splash ad failed to receive: \(errorCode)")
          // Transitions to main screen even on ad failure
      }

      // Ad impression (optional)
      func onAdImpression(_ ad: AdropSplashAd) {
          print("Splash ad impression")
      }
  }
  ```

  ```objc Objective-C theme={null}
  #pragma mark - AdropSplashAdDelegate

  // Splash ad closed (optional)
  - (void)onAdClose:(AdropSplashAd *)ad impressed:(BOOL)impressed {
      NSLog(@"Splash ad closed - Impressed: %@", impressed ? @"YES" : @"NO");

      // Transition to main screen
      MainViewController *mainViewController = [[MainViewController alloc] init];
      self.window.rootViewController = mainViewController;
  }

  // Ad received successfully (optional)
  - (void)onAdReceived:(AdropSplashAd *)ad {
      NSLog(@"Splash ad received successfully");
  }

  // Ad failed to receive (optional)
  - (void)onAdFailedToReceive:(AdropSplashAd *)ad :(AdropErrorCode)errorCode {
      NSLog(@"Splash ad failed to receive: %ld", (long)errorCode);
      // Transitions to main screen even on ad failure
  }

  // Ad impression (optional)
  - (void)onAdImpression:(AdropSplashAd *)ad {
      NSLog(@"Splash ad impression");
  }
  ```
</CodeGroup>

<Note>
  `AdropSplashAdViewController` automatically handles ad loading, display, and timer management. Even if the ad fails to load, `onAdClose` is automatically called to transition to the main screen.
</Note>

***

## Integrating with LaunchScreen

The system LaunchScreen is displayed first before showing the splash ad. For a natural user experience, it's recommended to match the style of the LaunchScreen with the splash ad screen.

### LaunchScreen.storyboard Setup

1. Open **LaunchScreen.storyboard** and set the background color to match the splash ad screen
2. Place the app logo in the center (matching the logo position of the splash ad)
3. Verify that `UILaunchStoryboardName` is set to `LaunchScreen` in Info.plist

```xml title="Info.plist" theme={null}
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
```

<Note>
  When the background color and logo position of the LaunchScreen match the splash ad screen, a smooth transition is possible at app launch.
</Note>

***

## Method 2: Using AdropSplashAdView

Use this when you want to compose a custom splash screen.

```swift theme={null}
import UIKit
import AdropAds

class CustomSplashViewController: UIViewController {
    private var splashAdView: AdropSplashAdView?
    private let logoImageView = UIImageView()

    override func viewDidLoad() {
        super.viewDidLoad()
        // AdropSplashAdView loads automatically on init, so create it first
        splashAdView = AdropSplashAdView(unitId: "YOUR_SPLASH_UNIT_ID")
        splashAdView?.delegate = self
        setupUI()
    }

    private func setupUI() {
        view.backgroundColor = .white

        // Set up app logo
        logoImageView.image = UIImage(named: "app_logo")
        logoImageView.contentMode = .scaleAspectFit
        logoImageView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(logoImageView)

        // Set up splash ad view
        guard let splashAdView = splashAdView else { return }
        splashAdView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(splashAdView)

        NSLayoutConstraint.activate([
            // Logo: center top of screen
            logoImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            logoImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 100),
            logoImageView.widthAnchor.constraint(equalToConstant: 200),
            logoImageView.heightAnchor.constraint(equalToConstant: 200),

            // Ad: bottom of screen
            splashAdView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            splashAdView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            splashAdView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
            splashAdView.heightAnchor.constraint(equalToConstant: 270)  // Fixed height
        ])
    }
}

// MARK: - AdropSplashAdViewDelegate
extension CustomSplashViewController: AdropSplashAdViewDelegate {
    // Splash ad closed (required)
    func onAdClose(_ adView: AdropSplashAdView, impressed: Bool) {
        print("Splash ad closed - Impressed: \(impressed)")
        transitionToMainScreen(impressed: impressed)
    }

    // Ad received successfully (optional)
    func onAdReceived(_ adView: AdropSplashAdView) {
        print("Splash ad view received successfully")
    }

    // Ad failed to receive (optional)
    func onAdFailedToReceive(_ adView: AdropSplashAdView, _ errorCode: AdropErrorCode) {
        print("Splash ad view failed to receive: \(errorCode)")
        // Transition to main screen on failure
        transitionToMainScreen(impressed: false)
    }

    // Ad impression (optional)
    func onAdImpression(_ adView: AdropSplashAdView) {
        print("Splash ad view impression")
    }
}

// MARK: - Navigation
extension CustomSplashViewController {
    private func transitionToMainScreen(impressed: Bool) {
        guard let window = view.window else { return }

        let mainViewController = MainViewController()
        window.rootViewController = mainViewController

        // Smooth transition animation
        UIView.transition(
            with: window,
            duration: 0.3,
            options: .transitionCrossDissolve,
            animations: nil,
            completion: nil
        )
    }
}
```

<Note>
  When using `AdropSplashAdView`, you must implement `AdropSplashAdViewDelegate`. The `onAdClose(impressed:)` method is <strong>required</strong>.
</Note>

***

## Method 3: SwiftUI Implementation

How to implement splash ads in a SwiftUI app.

### SwiftUI Wrapper

```swift theme={null}
import SwiftUI
import AdropAds

struct SplashAdView: UIViewControllerRepresentable {
    let unitId: String
    let logoImage: UIImage?
    @Binding var isPresented: Bool

    func makeUIViewController(context: Context) -> AdropSplashAdViewController {
        let controller = AdropSplashAdViewController(unitId: unitId)
        controller.logoImage = logoImage
        controller.delegate = context.coordinator
        return controller
    }

    func updateUIViewController(_ uiViewController: AdropSplashAdViewController, context: Context) {
        // No update needed
    }

    func makeCoordinator() -> Coordinator {
        Coordinator(isPresented: $isPresented)
    }

    class Coordinator: NSObject, AdropSplashAdDelegate {
        @Binding var isPresented: Bool

        init(isPresented: Binding<Bool>) {
            _isPresented = isPresented
        }

        func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
            print("Splash ad closed - Impressed: \(impressed)")
            DispatchQueue.main.async {
                self.isPresented = false
            }
        }

        func onAdReceived(_ ad: AdropSplashAd) {
            print("Splash ad received successfully")
        }

        func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
            print("Splash ad failed to receive: \(errorCode)")
        }

        func onAdImpression(_ ad: AdropSplashAd) {
            print("Splash ad impression")
        }
    }
}
```

### Using in SwiftUI App

```swift theme={null}
import SwiftUI
import AdropAds

@main
struct MyApp: App {
    init() {
        // Initialize SDK
        Adrop.initialize(production: false)
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State private var showSplash = true

    var body: some View {
        ZStack {
            if showSplash {
                SplashAdView(
                    unitId: "YOUR_SPLASH_UNIT_ID",
                    logoImage: UIImage(named: "app_logo"),
                    isPresented: $showSplash
                )
                .ignoresSafeArea()
            } else {
                MainView()
            }
        }
    }
}

struct MainView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Main Screen")
                    .font(.largeTitle)
            }
            .navigationTitle("Home")
        }
    }
}
```

***

## Delegate Methods

### AdropSplashAdDelegate

Delegate for using `AdropSplashAd`.

| Method                      | Required | Description                                                                  |
| --------------------------- | -------- | ---------------------------------------------------------------------------- |
| `onAdClose(impressed:)`     | Optional | Called when splash ad closes. Check ad impression with `impressed` parameter |
| `onAdReceived(_:)`          | Optional | Called when ad is received successfully                                      |
| `onAdFailedToReceive(_:_:)` | Optional | Called when ad fails to receive                                              |
| `onAdImpression(_:)`        | Optional | Called when ad impression is recorded                                        |

### AdropSplashAdViewDelegate

Delegate for using `AdropSplashAdView`.

| Method                      | Required     | Description                                                      |
| --------------------------- | ------------ | ---------------------------------------------------------------- |
| `onAdClose(impressed:)`     | **Required** | Called when splash ad closes. Must handle main screen transition |
| `onAdReceived(_:)`          | Optional     | Called when ad is received successfully                          |
| `onAdFailedToReceive(_:_:)` | Optional     | Called when ad fails to receive                                  |
| `onAdImpression(_:)`        | Optional     | Called when ad impression is recorded                            |

***

## Closure Callbacks

As an alternative to delegates, you can use closure-based callbacks on `AdropSplashAd`.

```swift theme={null}
let splashAd = AdropSplashAd(unitId: "YOUR_UNIT_ID")

splashAd.onAdReceived = { ad in
    print("Splash ad received")
}

splashAd.onAdFailedToReceive = { ad, errorCode in
    print("Splash ad failed: \(errorCode)")
}

splashAd.onAdImpression = { ad in
    print("Splash ad impression")
}

splashAd.onAdClose = { ad, impressed in
    print("Splash ad closed - Impressed: \(impressed)")
}
```

<Note>
  If both a delegate and closures are set, both will be called.
</Note>

***

## The impressed Parameter

The `impressed` parameter in the `onAdClose(_:impressed:)` method indicates whether the ad was actually displayed to the user.

```swift theme={null}
func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
    if impressed {
        print("Ad was displayed to the user")
        // Post-impression logic
    } else {
        print("Ad was not displayed (load failure or skipped)")
        // No-impression logic
    }

    // Transition to main screen
    transitionToMainScreen()
}
```

### When impressed is false

* Ad load failure
* Network error
* User skipped before seeing the ad
* No ad inventory

***

## Best Practices

### 1. Appropriate Timer Settings

Splash ads should not be displayed too short or too long.

```swift theme={null}
// AdropSplashAdViewController automatically manages the timer
// Default: 1 second (including ad load time)
```

### 2. Optimize Logo Image

Prepare the app logo in an appropriate size to minimize loading time.

```swift theme={null}
// Recommended logo size: 200x200 ~ 300x300 points
let logoImage = UIImage(named: "app_logo")  // Prepare @2x, @3x versions
```

### 3. Handle Failures

Ensure the app starts normally even when ad loading fails.

```swift theme={null}
func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
    print("Ad load failed: \(errorCode)")
    // Transition to main screen even on failure
    // AdropSplashAdViewController handles this automatically
}
```

### 4. Smooth Screen Transitions

Use natural animations when transitioning to the main screen.

```swift theme={null}
private func transitionToMainScreen() {
    guard let window = view.window else { return }

    let mainViewController = MainViewController()

    UIView.transition(
        with: window,
        duration: 0.3,
        options: .transitionCrossDissolve,
        animations: {
            window.rootViewController = mainViewController
        },
        completion: nil
    )
}
```

### 5. Separate Test and Production Environments

Test with separate development and production environments.

```swift theme={null}
#if DEBUG
let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
let isProduction = false
#else
let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
let isProduction = true
#endif

// Initialize SDK
Adrop.initialize(production: isProduction)

// Create splash ad
let splashViewController = AdropSplashAdViewController(
    unitId: splashUnitId
)
splashViewController.logoImage = UIImage(named: "app_logo")
```

***

## Complete SceneDelegate Example

```swift theme={null}
import UIKit
import AdropAds

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(
        _ scene: UIScene,
        willConnectTo session: UISceneSession,
        options connectionOptions: UIScene.ConnectionOptions
    ) {
        guard let windowScene = (scene as? UIWindowScene) else { return }

        // Set up window
        window = UIWindow(windowScene: windowScene)

        #if DEBUG
        let splashUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"
        #else
        let splashUnitId = "YOUR_PRODUCTION_SPLASH_UNIT_ID"
        #endif

        // Create splash ad view controller
        let splashViewController = AdropSplashAdViewController(
            unitId: splashUnitId
        )
        splashViewController.logoImage = UIImage(named: "app_logo")
        splashViewController.delegate = self

        // Set root view controller
        window?.rootViewController = splashViewController
        window?.makeKeyAndVisible()
    }
}

// MARK: - AdropSplashAdDelegate
extension SceneDelegate: AdropSplashAdDelegate {
    func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
        print("Splash ad closed - Impressed: \(impressed)")

        // Transition to main screen
        let mainViewController = MainViewController()
        let navigationController = UINavigationController(rootViewController: mainViewController)

        guard let window = window else { return }

        UIView.transition(
            with: window,
            duration: 0.3,
            options: .transitionCrossDissolve,
            animations: {
                window.rootViewController = navigationController
            },
            completion: nil
        )
    }

    func onAdReceived(_ ad: AdropSplashAd) {
        print("Splash ad received successfully")
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        print("Splash ad failed to receive: \(errorCode)")
        // AdropSplashAdViewController automatically calls onAdClose
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        print("Splash ad impression recorded")
    }
}
```

***

## Testing

### Test Unit ID

Use the test unit ID during development.

```swift theme={null}
// Test unit ID
let testUnitId = "PUBLIC_TEST_UNIT_ID_SPLASH"

// Or use AdropUnitId
let testUnitId = AdropUnitId.PUBLIC_TEST_UNIT_ID_SPLASH
```

<Warning>
  Make sure to use the actual unit ID created in the Ad Control console for production releases. No ad revenue is generated with test unit IDs.
</Warning>

### Debugging

Check ad events with logs.

```swift theme={null}
extension SceneDelegate: AdropSplashAdDelegate {
    func onAdReceived(_ ad: AdropSplashAd) {
        #if DEBUG
        print("Splash ad received")
        #endif
    }

    func onAdFailedToReceive(_ ad: AdropSplashAd, _ errorCode: AdropErrorCode) {
        #if DEBUG
        print("Splash ad failed: \(errorCode)")
        print("  - Check network status")
        print("  - Verify unit ID: \(ad.unitId)")
        #endif
    }

    func onAdImpression(_ ad: AdropSplashAd) {
        #if DEBUG
        print("Splash ad impression")
        #endif
    }

    func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
        #if DEBUG
        print("Splash ad closed")
        print("  - Impressed: \(impressed)")
        #endif
    }
}
```

***

## Troubleshooting

<AccordionGroup>
  <Accordion title="Splash screen not displayed">
    * Verify `window.rootViewController` is set correctly
    * Check if SceneDelegate is enabled (Info.plist)
    * Ensure SDK initialization is complete
  </Accordion>

  <Accordion title="Ad not loading">
    * Check network connection
    * Verify the unit ID is correct
    * Confirm `production: false` setting in test environment
    * Check onAdFailedToReceive error code
  </Accordion>

  <Accordion title="Not transitioning to main screen">
    * Verify `onAdClose(_:impressed:)` delegate is implemented
    * Ensure screen transition code runs on main thread

    ```swift theme={null}
    func onAdClose(_ ad: AdropSplashAd, impressed: Bool) {
        DispatchQueue.main.async {
            // Screen transition code
        }
    }
    ```
  </Accordion>

  <Accordion title="onAdClose not called when using AdropSplashAdView">
    * Verify `AdropSplashAdViewDelegate` is implemented
    * Check `splashAdView.delegate = self` is set
    * `onAdClose(impressed:)` method must be implemented
  </Accordion>
</AccordionGroup>

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Interstitial Ads" href="/sdk/ios/interstitial">
    Display interstitial ads during screen transitions
  </Card>

  <Card title="Banner Ads" href="/sdk/ios/banner">
    Implement banner ads
  </Card>

  <Card title="Native Ads" href="/sdk/ios/native">
    Custom design native ads
  </Card>

  <Card title="Rewarded Ads" href="/sdk/ios/rewarded">
    Provide user rewards
  </Card>
</CardGroup>
