The adTypes parameter in the code is responsible for the ad formats you are going to implement into your app. 

Appodeal supports all major mobile ad types:

  • Interstitial (AppodealAdTypeInterstitial): full-screen ads, that contain a static image or a skippable video.
  • Rewarded video (AppodealAdTypeRewardedVideo): non-skippable video ads that users may choose to watch to get a reward.
  • Non-skippable video (AppodealAdTypeNonSkippableVideo): video ads that must be watched until the end.
  • Native ads (AppodealAdTypeNativeAd): ads that can match the structure and style of an app and naturally continue the user experience.
  • Banner (AppodealAdTypeBanner): rectangular ads that occupy a spot within an app's layout
  • MREC (AppodealAdTypeMREC): medium-rectangule ads (300x250px) that appear within in-app content. It’s a deprecated ad format and is better to be replaced with native ads.

Important!

The SDK can't show ads in offline mode! You will get callback failToPresent, if you call showAd without internet connection.

Please note:

Ad types can be combined using "|" operator. For example, Appodeal.INTERSTITIAL | Appodeal.REWARDED_VIDEO.

Appodeal.NON_SKIPPABLE_VIDEO - the alias of Appodeal.REWARDED_VIDEO. Both of them shouldn't be used together.

If you are not sure, which ad formats would suit you the best, check out our FAQ.

Interstitial

1. Basic integration

import Appodeal

class YourViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad() 
        Appodeal.showAd(.interstitial, forPlacement: placement, rootViewController: self)
    }
}

2. Display interstitial

Appodeal.showAd(AppodealShowStyle.interstitial, rootViewController: self)

3. Check if interstitial is loaded

Appodeal.isReadyForShow(with: .interstitial)

4. Use interstitial callbacks

The callbacks are used to track different events in the lifecycle of an ad, e.g., when an ad was clicked on or closed. To get them, you need to set the delegate as follows:

// set delegate
Appodeal.setInterstitialDelegate(self)
Usually, the class that implements interstitials is also the delegate class. That’s why the delegate property can be set to self.

Now you can use the following callback methods:

extension YourViewController: AppodealInterstitialDelegate {
    // Method called when precache (cheap and fast load) or usual interstitial view did load
    //
    // - Warning: If you want show only expensive ad, ignore this callback call with precache equal to YES
    // - Parameter precache: If precache is YES it's mean that precache loaded
    func interstitialDidLoadAdIsPrecache(_ precache: Bool) {
        
    }

    // Method called if interstitial mediation failed
    func interstitialDidFailToLoadAd() {
        
    }
    
    // Method called if interstitial mediation was success, but ready ad network can't show ad or
    // ad presentation was to frequently according your placement settings
    func interstitialDidFailToPresent() {
        
    }
    
    // Method called when interstitial will display on screen
    func interstitialWillPresent() {
        
    }

    // Method called after interstitial leave screeen
    func interstitialDidDismiss() {
        
    }

    // Method called when user tap on interstitial
    func interstitialDidClick() {
        
    }
    
    // Method called when interstitial did expire and could not be shown
    func interstitialDidExpired(){
        
    }
}

All callbacks are called on the main thread.

5. Cache interstitials manually

To disable automatic caching for interstitials, use the code below before the SDK initialization:

Appodeal.setAutocache(false, types: .interstitial)
To cache interstitial use:
Appodeal.cacheAd(.interstitial)
Read more on manual caching in our FAQ.

Rewarded video

1. Basic integration

import Appodeal

class YourViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad() 
        Appodeal.showAd(.rewardedVideo, forPlacement: placement, rootViewController: self)
    }
}

2. Display rewarded video

Appodeal.showAd(AppodealShowStyle.rewardedVideo, rootViewController: self)

3. Check if rewarded video is loaded

Appodeal.isReadyForShow(with: .rewardedVideo)

4. Use rewarded video callbacks

The callbacks are used to track different events in the lifecycle of an ad, e.g., when an ad was clicked on or closed. To get them, you need to set the delegate as follows:

// set delegate
Appodeal.setRewardedVideoDelegate(self)
Usually, the class that implements rewarded video ads is also the delegate class. That’s why the delegate property can be set to self.

Now you can use the following callback methods:

extension YourViewController: AppodealRewardedVideoDelegate {
    // Method called when rewarded video loads
    //
    // - Parameter precache: If precache is YES it means that precached ad loaded
    func rewardedVideoDidLoadAdIsPrecache(_ precache: Bool) {
        
    }
    
    // Method called if rewarded video mediation failed
    func rewardedVideoDidFailToLoadAd() {
        
    }

    // Method called if rewarded mediation was successful, but ready ad network can't show ad or
    // ad presentation was too frequent according to your placement settings
    //
    // - Parameter error: Error object that indicates error reason
    func rewardedVideoDidFailToPresentWithError(_ error: Error) {
        
    }

    // Method called after rewarded video start displaying
    func rewardedVideoDidPresent() {
        
    }
    
    // Method called before rewarded video leaves screen
    //
    // - Parameter wasFullyWatched: boolean flag indicated that user watch video fully
    func rewardedVideoWillDismissAndWasFullyWatched(_ wasFullyWatched: Bool) {
        
    }

    //  Method called after fully watch of video
    //
    // - Warning: After call this method rewarded video can stay on screen and show postbanner
    // - Parameters:
    //   - rewardAmount: Amount of app curency tuned via Appodeal Dashboard
    //   - rewardName: Name of app currency tuned via Appodeal Dashboard
    func rewardedVideoDidFinish(_ rewardAmount: Float, name rewardName: String?) {
        
    }

    // Method is called when rewarded video is clicked
    func rewardedVideoDidClick() {

    }

    // Method called when rewardedVideo did expire and can not be shown
    func rewardedVideoDidExpired(){
        
    }
}

All callbacks are called on the main thread.

5. Cache rewarded video manually

To disable automatic caching for rewarded videos, use the code below before the SDK initialization:

Appodeal.setAutocache(false, types:.rewardedVideo)
To cache rewarded video use:
Appodeal.cacheAd(.rewardedVideo)
Read more on manual caching in our FAQ.

6. Advanced

Server-to-server (S2S) rewarded video callbacks

To secure your apps economy we offer S2S reward callbacks. To validate each reward you need to setup a callback URL on your server that will receive the reward information. We will pass the user data to your callback URL that you will need to validate and adjust the user balance accordingly.

1. Create the reward callback URL on your server that will receive the reward information.

2. Fill the created URL and the encryption key in the app settings in your dashboard.

3. The reward callback will be sent to your URL using GET request with two parameters:

{http:/example.com/reward}?data1={data1}&data2={data2}
4. Your URL should decrypt the data and validate it.

5. Check impression_id for uniqueness and store it in your system to prevent the duplication of transactions.

To set user ID, use the Appodeal.getUserSettings(this).setUserId("User#123") method before the SDK initialization.

We offer sample scripts in PHP, Ruby, Java, Node.js, Python 3 and C# to decrypt the data. If you need samples in other languages, please contact our support team and we will provide it to you.

Sample in PHP: reward.php.

Sample in Ruby: reward.rb.

Sample in Java: reward.java.

Sample in Node.js: reward.js .

Sample in Python 3: reward.py.

Sample in C#: reward.cs.

Get reward data for a specific placement

To get reward details (currency, name and amount) for any placement, use the rewardForPlacement:(NSString *)placement method:

let rewardCurrencyName = Appodeal.reward(forPlacement:"placement").currencyName
let rewardAmount = Appodeal.reward(forPlacement:"placement").amount

Non-skippable video

1. Basic integration

import Appodeal

class YourViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad() 
        Appodeal.showAd(.nonSkippableVideo, forPlacement: placement, rootViewController: self)
    }
}

2. Display non-skippable video

Appodeal.showAd(AppodealShowStyle.nonSkippableVideo, rootViewController: self)

3. Check if non-skippable video is loaded

Appodeal.isReadyForShow(with: .nonSkippableVideo)

4. Use non-skippable video callbacks

The callbacks are used to track different events in the lifecycle of an ad, e.g. when an ad was clicked on or closed. To get them, you need to set the delegate as follows:

// set delegate
Appodeal.setNonSkippableVideoDelegate(self)
Usually, the class that implements non-skippable video ads is also the delegate class. That’s why the delegate property can be set to self.

Now you can use the following callback methods:

extension YourViewController: AppodealNonSkippableVideoDelegate {
    
    // Method called when non skippable video loads
    //
    // - Parameter precache: If precache is YES it means that precached ad loaded
    func nonSkippableVideoDidLoadAdIsPrecache(_ precache: Bool) {
        
    }
    
    // Method called if non skippable video mediation failed
    func nonSkippableVideoDidFailToLoadAd() {
        
    }

    // Method called if rewarded mediation was successful, but ready ad network can't show ad or
    // ad presentation was too frequent according to your placement settings
    //
    // - Parameter error: Error object that indicates error reason
    func rewardedVideoDidFailToPresentWithError(_ error: Error) {
        
    }

    // Method called after non skippable video start displaying
    func nonSkippableVideoDidPresent() {
        
    }
    
    // Method called before non skippable video leaves screen
    //
    // - Parameter wasFullyWatched: boolean flag indicated that user watch video fully
    func nonSkippableVideoWillDismissAndWasFullyWatched(_ wasFullyWatched: Bool) {
        
    }

    //  Method called after fully watch of video
    //
    // - Warning: After call this method non skippable video can stay on screen and show postbanner
    func nonSkippableVideoDidFinish() {
        
    }
    
    // Method called when nonSkippableVideo did expire and could not be shown
    func nonSkippableVideoDidExpired(){
        
    }
}

All callbacks are called on the main thread.

5. Cache non-skippable videos manually

To disable automatic caching for non-skippable videos, use the code below before the SDK initialization:

Appodeal.setAutocache(false, types:.nonSkippableVideo)
To cache non-skippable video use:
Appodeal.cacheAd(.nonSkippableVideo)
Read more on manual caching in our FAQ.

Native Ads

1. Basic integration

Native AdQueue is the new native ad implementation and management tool in the Appodeal SDK. You no longer need to load Native Ads up manually. All you have to do is to set the desired amount in AdQueue, and it will load new items automatically.

Be careful using AdQueue: if your app loads too many ads but is not able to use it, the ad network can either lower the cost of each impression for you or limit your ability to load native ads.

import Appodeal
class ViewController: UIViewController {
    var adQueue : APDNativeAdQueue!
}

2. Configure settings for native ads

In adQueue.settings you can set the following parameters for the native ads of your app:

adQueue.settings setting name

Type

Appointment

Possible values

type

APDNativeAdType

Native Ad Type

APDNativeAdTypeAuto

APDNativeAdTypeVideo

APDNativeAdTypeNoVideo

adViewClass

Class <APDNativeAdView>

Template class

Default template: APDDefaultNativeAdView.class

autocacheMask

APDNativeResourceAutocacheMask

Mask for caching media files

Icons caching: (APDNativeResourceAutocacheIcon): 1

Image and Video caching (APDNativeResourceAutocacheMedia): 2

Cache all media files: 3

3. Initialize a specific type of native ads

The Appodeal SDK provides both static and video types of native ads.

To implement static native ads into your app, use the following code:

class ViewController: UIViewController {
    var adQueue : APDNativeAdQueue!
    override func viewDidLoad() {
        super.viewDidLoad()
        adQueue.settings.adViewClass = TemplateClass.self
        adQueue.settings.autocacheMask = [.icon, .media]
        adQueue.settings.type = .novideo
        
        adQueue.loadAd()
  }
}
To implement native video ads, use the following code:
class ViewController: UIViewController {
    var adQueue : APDNativeAdQueue!
    override func viewDidLoad() {
        super.viewDidLoad()
        adQueue.settings.adViewClass = TemplateClass.self
        adQueue.settings.autocacheMask = [.icon, .media]
        adQueue.settings.type = .video
        
        adQueue.loadAd()
  }
}
The aspect ratio of native video ads in the Appodeal SDK is 16:9, the file size is about 1-3 Mb.

There are two types of native video ads in the Appodeal SDK:

  • skippable - if “skippable” flag is stated, then the video can be skipped after 5 seconds from the start;
  • muted - if “muted” flag is stated, then the video will be played with no sound.

4. Cache native ads

You can set the number of ads you need to cache on your Appodeal Dashboard.

Native AdQueue also allows to cache ads with the setMaxAdSize method, but remember that it is considered deprecated since v. 2.2.0.

Example:

self.adQueue.setMaxAdSize(5) //deprecated

5. Use native ads callbacks

The callbacks are used to track different events in the lifecycle of an ad, e.g., when an ad was clicked on or closed. To get them, you need to set the delegate as follows:

1. Add APDNativeAdQueueDelegate and APDNativeAdPresentationDelegate to the header file:

class YourViewController: APDNativeAdQueueDelegate, APDNativeAdPresentationDelegate { }
2. Set the delegate:
self.adQueue.delegate = self
self.currentAd.delegate = self
3. Implement the following functions:
extension MainViewController : APDNativeAdPresentationDelegate {
    
    func nativeAdWillLogImpression(_ nativeAd: APDNativeAd!) {
    }
    
    func nativeAdWillLogUserInteraction(_ nativeAd: APDNativeAd!) {
    }
}

extension MainViewController : APDNativeAdQueueDelegate {
    
    func adQueue(_ adQueue: APDNativeAdQueue!, failedWithError error: Error!) {
    }
    
    func adQueueAdIsAvailable(_ adQueue: APDNativeAdQueue!, ofCount count: UInt) {
    }
    
}

All callbacks are called on the main thread.

6. Use custom templates for native ads

To use your custom templates for native ads, simply state your templates class in adQueue.setting.adViewClass, as follows:

adQueue.settings.adViewClass = YourNativeAdViewTemplate.self
Your template class should conform the following protocol:
protocol APDNativeAdView {
 func titleLabel() -> UILabel
 func callToActionLabel() -> UILabel
// Optional
 func descriptionLabel() -> UILabel
 func iconView() -> UIImageView
 func mediaContainerView() -> UIView
 func contentRatingLabel() -> UILabel
 func adChoicesView() -> UIView
 func setRating(_ rating: NSNumber)
 static func nib() -> UINib
}

extension APDNativeAdView {
 func descriptionLabel() -> UILabel {}
 func iconView() -> UIImageView {}
 func mediaContainerView() -> UIView {}
 func contentRatingLabel() -> UILabel {}
 func adChoicesView() -> UIView {}
 func setRating(_ rating: NSNumber) {}
}
The objects, mentioned in this protocol, are:

  • titleLabel - container for title text;
  • callToActionLabel - container for call-to-action text;
  • descriptionLabel - container for description text;
  • iconView - container for icon image;
  • mediaContainerView - container for media files (images and video files);
  • contentRatingLabel - container for showing rating of the content;
  • adChoicesView - container for showing adChoice;
  • rating - container for showing rating of the app;
  • nib - nib-file for template.

Note:

All views should be enclosed in a single superview. If YourNativeAdViewTemplate inherits from UITableViewCell(UICollectionViewCell), these views should be contained in the hierarchy of contentView.

7. Get all native ads from Native AdQueue

import UIKit
import Appodeal

class ViewController: UIViewController {
    
    @IBOutlet weak var nativeAdView: UIView!
    var nativeAdQueue: APDNativeAdQueue!
    var nativeArray: [APDNativeAd] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        nativeAdQueue = APDNativeAdQueue()
        nativeAdQueue.settings = APDNativeAdSettings.default()
        nativeAdQueue.settings.adViewClass = CustomNativeAdView.self
        nativeAdQueue.delegate = self
        nativeAdQueue.settings.autocacheMask = [.icon, .media]
        
        nativeAdQueue.loadAd()
    }
    
    @IBAction func presentNativeAd(_ sender: Any) {
        let nativeAd = nativeArray.first
        if let nativeAd = nativeAd {
            nativeAd.delegate = self
            do {
                let adView = try nativeAd.getViewForPlacement("default", withRootViewController: self)
                adView.frame = nativeAdView.bounds
                nativeAdView.addSubview(adView)
            } catch {
                print("error")
            }
        }
    }
}

extension ViewController: APDNativeAdQueueDelegate, APDNativeAdPresentationDelegate {
    func adQueueAdIsAvailable(_ adQueue: APDNativeAdQueue, ofCount count: UInt) {
        if nativeArray.count > 0 {
            return
        } else {
            nativeArray.append(contentsOf: adQueue.getNativeAds(ofCount: 1))
            nativeArray.map{( $0.delegate = self )}
        }
    }
}

Native ads requirements

  • All of the fields of native ad marked as mandatory must be displayed.
  • Every ad should have a sign that clearly indicates that it is an ad. For example "Ad" or "Sposored".
  • Provided images can be resized to fit your ad space but should not be significantly distorted or cropped.

8. Native Ad object

The NativeAd object has the following characteristics in the Appodeal SDK. All of the fields, marked as “Mandatory”, must be displayed:

Name of fieldRequired?Description
NSString *title;MandatoryThe title of the native ad. Minimum 25 symbols of the title should always be displayed. You can add ellipsis at the end if the title is longer.
NSString *subtitleOptionalThe subtitle of the native ad.
NSString *descriptionTextOptionalThe text description of the native ad. If you choose to display the description, you should display minimum 75 characters. You can add ellipsis at the end.
NSString *callToActionTextMandatoryThe call to action text. Should be displayed without truncation on a visible button.
NSString *contentRatingOptionalRating of the content.
NSNumber *starRatingOptionalRating of the app in [0-5] range.
APDImage *mainImageOptionalBitmap of an image. An ad object contains both icon and image. It’s mandatory to use at least one of these elements. Deprecated method. NativeMediaView should be used instead of it to show images or videos.
APDImage *iconImageMandatoryBitmap of an icon. An ad object contains both icon and image. It’s mandatory to use at least one of these elements.
UIView *adChoicesViewMandatoryView. If it doesn’t return null, it’s mandatory to display the provider icon in any corner of the native ad. Used by some networks to display AdChoices or the privacy icon.

9. Common mistakes with native ads

  • No ad attribution or AdChoices icon

The majority of ad networks require from publishers to add a special mark to a native ad, so users don’t mistake them for content. That’s why you always need to make sure, that native ads in your app have the ad attribution (e.g., “Ad”) or the AdChoices icon.

  • Absence of the required native ad elements

Every native ad should contain:

    • title;
    • call-to-action button;
    • ad attribution or AdChoices icon;
    • icon, image or video.

  • Native ad elements alteration

Advertisers expect that their ads will be displayed clearly and without any alteration. You can scale buttons and images, but you shouldn't crop, cover or distort them.

  • Overlaying elements of native ads on each other

Make sure, that all elements of a native ad are visible and not overlaid.

Banner

1. Basic integration

Banner is a singleton now, if you are using bannerTop or bannerBottom on different controllers then the SDK will use the same banner instance.

class YourViewController : UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad() 
        Appodeal.showAd(.bannerBottom, forPlacement: placement, rootViewController: self)
    }
}

2. Display banner at the bottom of the screen

Display ad banner at the bottom of the screen:

Appodeal.showAd(.bannerBottom, forPlacement: placement, rootViewController: self)

3. Display banner at the top of the screen

Display ad banner at the top of the screen:

Appodeal.showAd(.bannerTop, forPlacement: placement, rootViewController: self)

4. Display banner in programmatically created view

You can also add the Appodeal banner to your view hierarchy manually.

For example:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if let banner = Appodeal.banner() {
            self.view.addSubview(banner)
            banner.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 50)
        }
    }

Important!

Custom BannerView must be on the top of the hierarchy and mustn't be overlapped by another views.

5. Check if banner is loaded

Appodeal.isReadyForShow(with: .banner)

6. Use banner callbacks

Callbacks are used to track different lifecycle events of an ad, e.g., when a banner has successfully loaded or is about to appear. To get them, you need to set the delegate as follows:

//set delegate
Appodeal.setBannerDelegate(self)
Usually, the class that implements banners is also the delegate class. That’s why the delegate property can be set to self.

Now you can use the following callback methods:

    func bannerDidLoadAdIsPrecache(_ precache: Bool){
        NSLog("banner was loaded")       
    }
    func bannerDidFailToLoadAd(){
        NSLog("banner failed to load");        
    }
    func bannerDidClick(){
        NSLog("banner was clicked")
    }
    func bannerDidShow(){
        NSLog("banner was shown")
    }
    func bannerDidExpired(){
        NSLog("banner did expire and could not be shown")
    }

All callbacks are called on the main thread.

If automatic caching is ON for the Banner ad type, do not show banner in the bannerDidLoadAdIsPrecache callback. The banner will be refreshed automatically after the first show.

7. Hide banner

To remove banner from your view hierarchy:

Appodeal.hideBanner()

8. Cache banner manually

To disable automatic caching for banners, use the code below before the SDK initialization:

Appodeal.setAutocache(false, types:.banner)
To cache banners use:
Appodeal.setAutocache(true, types:.banner)
Read more on manual caching in our FAQ.

9. Advanced banner integration

Advanced BannerView integration

If the basic integration is not appropriate for you due to the complex views hierarchy of your app, you can use AppodealBannerView UIView subclass to integrate banners.

import UIKit
import Appodeal

class YourViewController : UIViewController, AppodealBannerViewDelegate {

  override func viewDidLoad () {
    super.viewDidLoad()
    // required: init ad banner
    var bannerView: AppodealBannerView!
    bannerView.init(size: bannerSize, rootViewController: self);

    // optional: set delegate
    bannerView.setDelegate(self);

    // required: add banner to superview and call -loadAd to start banner loading
    self.view addSubview(bannerView);
    bannerView.loadAd();
  }

  // optional: implement any of AppodealBannerViewDelegate methods
    func bannerViewDidLoadAd(_ bannerView: APDBannerView, isPrecache precache: Bool){
        NSLog("Banner view was loaded")
    }

    func bannerViewDidRefresh(_ bannerView: APDBannerView){
        NSLog("banner view was refreshed")
    }
    func bannerView(_ bannerView: APDBannerView, didFailToLoadAdWithError error: Error!){
        NSLog("banner view failed to load")
    }
    func bannerViewDidInteract(_ bannerView: APDBannerView){
        NSLog("banner view was clicked")
    }
    func bannerViewExpired(_ bannerView: APDBannerView){
        NSLog("banner view expired")
    }
}

 Enable smart-banners

Smart banners are the banner ads which automatically fit the screen/container size. Using them helps to deal with the increasing fragmentation of the screen sizes on different devices. To enable them, use the following method:

//for top/bottom banners allows banner view to resize automatically to fit device screen
Appodeal.setSmartBannersEnabled(true)
//for banner view allows banner view to resize automatically to fit device screen
bannerView.usesSmartSizing = true

 Change banner background

This method allows to create a grey background for banner ads: 

//for top/bottom banners
Appodeal.setBannerBackgroundVisible(true)

//for bannerView
bannerView.backgroundVisible = true

 Enable banner refresh animation

//for top/bottom banners
Appodeal.setBannerAnimationEnabled(true)

//for bannerView
bannerView.bannerAnimationEnabled = true
 

MREC

It’s a deprecated ad format and it is recommended to use native ads instead.

1. Basic integration

Class AppodealMRECView is a subclass of AppodealBannerViewAppodealMRECView has size 300x250.

import UIKit
import Appodeal

class YourViewController: UIViewController, AppodealBannerViewDelegate {

  override func viewDidLoad () {
    super.viewDidLoad()
    // required: init ad banner
    let mrecView: AppodealMRECView = AppodealMRECView()
    mrecView.usesSmartSizing = false
    mrecView.rootViewController = self

    // optional: set delegate
    mrecView.delegate = self

    // required: add banner to superview and call -loadAd to start banner loading
    self.view.addSubview(mrecView)
    mrecView.loadAd()
  }

  // optional: implement any of AppodealBannerViewDelegate methods
    func bannerViewDidLoadAd(_ bannerView: APDBannerView, isPrecache precache: Bool) {
        NSLog("bannerView was loaded")       
    }
    func bannerView(_ bannerView: APDBannerView, didFailToLoadAdWithError error: Error) {
        NSLog("bannerView failed to load");        
    }
    func bannerViewDidInteract(_ bannerView: APDBannerView) {
        NSLog("bannerView was clicked")
    }
    func bannerViewDidShow(_ bannerView: APDBannerView) {
        NSLog("bannerView was shown")
    }
    func bannerViewExpired(_ bannerView: APDBannerView) {
        NSLog("bannerView did expire and could not be shown")
    }
}

2. Use MREC callbacks

Callbacks are used to track different lifecycle events of an ad, e.g., when a banner has successfully loaded or is about to appear. To get them, you need to set the delegate as follows:

//set delegate
Appodeal.setBannerDelegate(self)
Usually, the class that implements banners is also the delegate class. That’s why the delegate property can be set to self.

Now you can use the following callback methods:

    func bannerDidLoadAdIsPrecache(_ precache: Bool) { } //banner was loaded (precache flag shows if the loaded ad is precache)
    func bannerDidLoadAd() { } //banner was loaded -- deprecated, use `bannerDidLoadAdIsPrecache:` instead
    func bannerDidRefresh() { } //banner was refreshed -- deprecated, use `bannerDidShow` instead
    func bannerDidShow() { } //banner was shown
    func bannerDidFailToLoadAd() { } //banner failed to load
    func bannerDidClick() { } //banner was clicked
    func bannerDidExpired() { } //banner did expire and could not be shown

All callbacks are called on the main thread.

3. Check if MREC is loaded

mrec.isReady //for MREC


banner.isReady //for banner


Appodeal.isReadyForShow(with: .bannerBottom) //for banner bottom (can check for .bannerTop)

4. Cache MREC manually

MREC does not support autocache.