Overview
Popup ads are ad formats that appear on screen at specific moments. They can be displayed at desired timings such as app launch, content load completion, or specific event occurrences. Users can close them by tapping the close button or selecting “Don’t show for today.”
Features
- Popup format displayed at center or bottom of screen
- Supports both image and video ads
- Provides close, dim (background) click, and “Don’t show for today” options
- Customizable background color, text color, etc.
- Non-intrusive yet effective ad experience
Use test unit IDs in development environment. See the Test Unit IDs section.
Implementation Steps
Implement popup ads in 4 steps:
- Initialize - Create AdropPopupAd instance
- Set Delegates - Set delegates to receive ad and close events
- Load Ad - Request and receive ad
- Show Ad - Display ad on screen
UIKit Implementation
Basic Implementation
import AdropAds
class ViewController: UIViewController {
private var popupAd: AdropPopupAd?
override func viewDidLoad() {
super.viewDidLoad()
loadPopupAd()
}
// 1. Initialize and load ad
private func loadPopupAd() {
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.delegate = self
popupAd?.closeDelegate = self
popupAd?.load()
}
// 2. Show ad
private func showPopupAd() {
guard let popupAd = popupAd,
popupAd.isLoaded else { return }
popupAd.show(fromRootViewController: self)
}
}
Delegate Implementation
// Ad delegate implementation
extension ViewController: AdropPopupAdDelegate {
// Ad received successfully (required)
func onAdReceived(_ ad: AdropPopupAd) {
print("Popup ad received")
// Show ad when ready
showPopupAd()
}
// Ad receive failed (required)
func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
print("Popup ad failed to receive: \(errorCode)")
}
// Ad impression (optional)
func onAdImpression(_ ad: AdropPopupAd) {
print("Popup ad impression")
}
// Ad clicked (optional)
func onAdClicked(_ ad: AdropPopupAd) {
print("Popup ad clicked")
}
// Before showing popup ad (optional)
func onAdWillPresentFullScreen(_ ad: AdropPopupAd) {
print("About to show popup ad")
}
// After showing popup ad (optional)
func onAdDidPresentFullScreen(_ ad: AdropPopupAd) {
print("Popup ad shown")
}
// Before dismissing popup ad (optional)
func onAdWillDismissFullScreen(_ ad: AdropPopupAd) {
print("About to dismiss popup ad")
}
// After dismissing popup ad (optional)
func onAdDidDismissFullScreen(_ ad: AdropPopupAd) {
print("Popup ad dismissed")
// Preload next ad
loadPopupAd()
}
// Popup ad show failed (optional)
func onAdFailedToShowFullScreen(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
print("Popup ad failed to show: \(errorCode)")
}
}
// Close delegate implementation
extension ViewController: AdropPopupAdCloseDelegate {
// Close button clicked (optional)
func onClosed(_ ad: AdropPopupAd) {
print("Popup ad close button clicked")
}
// Dim (background) clicked (optional)
func onDimClicked(_ ad: AdropPopupAd) {
print("Popup ad dim area clicked")
}
// "Don't show for today" clicked (optional)
func onTodayOffClicked(_ ad: AdropPopupAd) {
print("Don't show for today selected")
// The SDK automatically handles hiding the ad for today.
// Use this callback for analytics or custom UI updates.
}
}
SwiftUI Implementation
In SwiftUI, use UIViewControllerRepresentable or get the rootViewController from UIWindow to display.
ViewModel Pattern
import SwiftUI
import AdropAds
// ViewModel
class PopupAdViewModel: ObservableObject {
@Published var isAdReady = false
@Published var isAdShowing = false
private var popupAd: AdropPopupAd?
init() {
loadAd()
}
func loadAd() {
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.delegate = self
popupAd?.closeDelegate = self
popupAd?.load()
}
func showAd() {
guard let popupAd = popupAd,
let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.windows.first?.rootViewController else {
return
}
popupAd.show(fromRootViewController: rootViewController)
}
}
// Ad delegate
extension PopupAdViewModel: AdropPopupAdDelegate {
func onAdReceived(_ ad: AdropPopupAd) {
DispatchQueue.main.async {
self.isAdReady = true
}
}
func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
print("Ad receive failed: \(errorCode)")
}
func onAdDidPresentFullScreen(_ ad: AdropPopupAd) {
DispatchQueue.main.async {
self.isAdShowing = true
}
}
func onAdDidDismissFullScreen(_ ad: AdropPopupAd) {
DispatchQueue.main.async {
self.isAdShowing = false
self.isAdReady = false
}
// Preload next ad
loadAd()
}
}
// Close delegate
extension PopupAdViewModel: AdropPopupAdCloseDelegate {
func onClosed(_ ad: AdropPopupAd) {
print("Popup ad closed")
}
func onDimClicked(_ ad: AdropPopupAd) {
print("Popup ad dim clicked")
}
func onTodayOffClicked(_ ad: AdropPopupAd) {
print("Don't show for today selected")
// The SDK automatically handles hiding the ad for today.
// Use this callback for analytics or custom UI updates.
}
}
// View
struct ContentView: View {
@StateObject private var adViewModel = PopupAdViewModel()
var body: some View {
VStack {
Text("Popup Ad Example")
.font(.title)
Button("Show Popup Ad") {
adViewModel.showAd()
}
.disabled(!adViewModel.isAdReady)
.padding()
}
.onAppear {
// Auto show on app start
if adViewModel.isAdReady {
adViewModel.showAd()
}
}
}
}
Customization
You can customize the appearance of popup ads.
Set Background Color and Text Color
private func loadPopupAd() {
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.delegate = self
popupAd?.closeDelegate = self
// Set background color
popupAd?.backgroundColor = UIColor.black.withAlphaComponent(0.8)
// "Don't show for today" text color
popupAd?.hideForTodayTextColor = UIColor.white
// Close button text color
popupAd?.closeTextColor = UIColor.white
// CTA button text color
popupAd?.ctaTextColor = UIColor.white
popupAd?.load()
}
Customization Options
| Property | Type | Description | Default |
|---|
backgroundColor | UIColor? | Action bar background color | nil |
hideForTodayTextColor | UIColor? | ”Don’t show for today” text color | White |
closeTextColor | UIColor? | Close button text color | White |
ctaTextColor | UIColor? | CTA (Call to Action) button text color | White |
Delegate Methods
Required Methods
Called when ad is received successfully. You can call show() at this point to display the ad.
onAdFailedToReceive
(AdropPopupAd, AdropErrorCode) -> Void
Called when ad fails to load. You can check the cause of failure through the error code.
Optional Methods
Called when ad impression is recorded.
Called when user clicks the ad.
onAdWillPresentFullScreen
Called just before popup ad is displayed.
Called immediately after popup ad is displayed on screen.
onAdWillDismissFullScreen
Called just before popup ad is dismissed.
Called immediately after popup ad is dismissed. Good time to preload the next ad.
onAdFailedToShowFullScreen
(AdropPopupAd, AdropErrorCode) -> Void
Called when ad fails to show. You can check the cause of failure through the error code.
All methods are optional.
Called when user clicks the close button.
Called when user clicks outside the popup (dim area).
Called when user selects “Don’t show for today.” You can save the date in this callback to prevent showing ads for the rest of the day.
Custom Click Handling
You can take control of ad click behavior by using useCustomClick. When enabled, the SDK will not automatically open the destination URL on click, and you can handle it yourself.
useCustomClick
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.useCustomClick = true
popupAd?.delegate = self
popupAd?.load()
When useCustomClick is true, the SDK will not open the destination URL automatically when the ad is clicked. The onAdClicked delegate callback will still fire, and you can use the open() method or handle navigation yourself.
open()
Opens the destination URL of the ad. Can optionally pass a custom URL.
// Open the ad's default destination URL
popupAd?.open()
// Open a custom URL
popupAd?.open("https://example.com")
// Open using in-app browser
popupAd?.open(nil, useInAppBrowser: true)
close()
Programmatically dismiss the popup ad.
Properties
| Property | Type | Description |
|---|
unitId | String | The ad unit ID |
isLoaded | Bool | Whether the ad has been loaded |
useCustomClick | Bool | Whether to handle ad clicks manually |
destinationURL | String? | Destination URL of the currently displayed ad |
creativeId | String? | Creative ID of the currently displayed ad |
txId | String | Transaction ID of the currently displayed ad |
txIds | [String] | All transaction IDs of loaded ads |
campaignId | String | Campaign ID of the currently displayed ad |
campaignIds | [String] | All campaign IDs of loaded ads |
creativeIds | [String] | All creative IDs of loaded ads |
browserTarget | BrowserTarget? | How to open URLs on ad click |
Closure-based Callbacks
In addition to delegates, you can also use closure-based callbacks. This can be convenient when you don’t want to implement a full delegate pattern.
let popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
// Ad events
popupAd.onAdReceived = { ad in
print("Ad received")
}
popupAd.onAdFailedToReceive = { ad, errorCode in
print("Ad failed: \(errorCode)")
}
popupAd.onAdClicked = { ad in
print("Ad clicked, destination: \(ad.destinationURL ?? "")")
}
popupAd.onAdImpression = { ad in
print("Ad impression")
}
popupAd.onAdWillPresentFullScreen = { ad in
print("Will present")
}
popupAd.onAdDidPresentFullScreen = { ad in
print("Did present")
}
popupAd.onAdWillDismissFullScreen = { ad in
print("Will dismiss")
}
popupAd.onAdDidDismissFullScreen = { ad in
print("Did dismiss")
}
popupAd.onAdFailedToShowFullScreen = { ad, errorCode in
print("Failed to show: \(errorCode)")
}
// Close events
popupAd.onClosed = { ad in
print("Closed")
}
popupAd.onDimClicked = { ad in
print("Dim clicked")
}
popupAd.onTodayOffClicked = { ad in
print("Today off clicked")
}
popupAd.load()
Delegate callbacks and closure-based callbacks can be used simultaneously. Both will be called.
Implementing “Don’t Show for Today”
How to properly handle when users select “Don’t show for today.”
The SDK automatically manages the “Don’t Show for Today” state. The following example shows how to add custom behavior alongside the built-in handling.
Implementation
The SDK automatically skips loading when the user has selected “Don’t show for today.” Simply call load() — the SDK handles the rest.
class PopupAdManager {
private var popupAd: AdropPopupAd?
// Load and show ad
func loadAndShowAd(from viewController: UIViewController) {
popupAd = AdropPopupAd(unitId: "YOUR_POPUP_UNIT_ID")
popupAd?.delegate = self
popupAd?.closeDelegate = self
popupAd?.load()
}
}
extension PopupAdManager: AdropPopupAdDelegate {
func onAdReceived(_ ad: AdropPopupAd) {
// Auto show after receiving ad
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.windows.first?.rootViewController {
ad.show(fromRootViewController: rootViewController)
}
}
func onAdFailedToReceive(_ ad: AdropPopupAd, _ errorCode: AdropErrorCode) {
print("Ad receive failed: \(errorCode)")
}
}
extension PopupAdManager: AdropPopupAdCloseDelegate {
func onTodayOffClicked(_ ad: AdropPopupAd) {
print("Don't show for today selected")
// The SDK automatically handles hiding the ad for today.
// Use this callback for analytics or custom UI updates.
}
}
Best Practices
1. Appropriate Display Timing
Popup ads are effective when shown at these timings:
// ✅ Good: On app launch
func applicationDidFinishLaunching() {
loadAndShowPopupAd()
}
// ✅ Good: After content load completes
func onContentLoaded() {
if shouldShowPopupAd() {
showPopupAd()
}
}
// ✅ Good: After specific event completes
func onAchievementUnlocked() {
showPopupAd()
}
// ❌ Bad: While user is working
func onUserTyping() {
showPopupAd() // Disrupts user experience
}
2. Respect “Don’t Show for Today”
If user selects “Don’t show for today,” make sure to honor it.
func shouldShowPopupAd() -> Bool {
// Check "Don't show for today"
guard canShowAdToday() else {
return false
}
// Check other conditions
return true
}
3. Frequency Capping
Don’t show popup ads too frequently.
class PopupAdFrequencyManager {
private let lastShownKey = "popupAd_lastShown"
private let minimumInterval: TimeInterval = 3600 // 1 hour
func canShowAd() -> Bool {
// Check "Don't show for today"
guard canShowAdToday() else {
return false
}
// Check minimum time interval
guard let lastShown = UserDefaults.standard.object(forKey: lastShownKey) as? Date else {
return true
}
return Date().timeIntervalSince(lastShown) >= minimumInterval
}
func recordAdShown() {
UserDefaults.standard.set(Date(), forKey: lastShownKey)
}
}
Test Unit IDs
Use the following test unit IDs during development and testing.
| Ad Type | Test Unit ID |
|---|
| Popup (Bottom Image) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM |
| Popup (Center Image) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER |
| Popup Video (Bottom 16:9) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_16_9 |
| Popup Video (Bottom 9:16) | PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM_VIDEO_9_16 |
| Popup Video (Center 16:9) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_16_9 |
| Popup Video (Center 9:16) | PUBLIC_TEST_UNIT_ID_POPUP_CENTER_VIDEO_9_16 |
Make sure to use actual unit IDs created in Ad Control Console for production deployment.
Getting Started
SDK installation and initialization
Interstitial Ads
Implementing interstitial ads
Rewarded Ads
Implementing rewarded ads
Banner Ads
Implementing banner ads