Overview

Getting Started with iOS SDK Integration

Integrating and monetizing with InMobi SDK is easy. To begin, download our latest iOS SDK (ver 920) here or from Cocoapods.

Note

1. The latest version of InMobi SDK supports iOS 9 or higher. Also, this version of iOS SDK requires XCode 12.5 or higher.
2. We recommend calling all InMobi APIs on the main thread.

Add the InMobi SDK

Option 1: Integration via Cocoapods

  1. If you are not already using Cocoapods, go to your Xcode project directory and create a pod file using the command below.

    pod init
    
  2. Add the following to Podfile.

    pod 'InMobiSDK'
    
  3. Once you have added it to the pod file, run the command below to complete the task for dependency. You now have a workspace with the pods.

    pod update
    


Option 2: Integrating the framework directly

Alternatively, you can integrate the framework directly.

1. Add the following MANDATORY frameworks to your Xcode project:

  • InMobiSDK.xcframework from the downloaded InMobi iOS SDK bundle
  • libsqlite3.0.tbd
  • libz.tbd
  • WebKit.framework

2. Add -ObjC flag to the Other Linker Flags:

  1. Open your project in Xcode.
  2. Select Application Target > Build Settings.
  3. In the Search box, search for Other Linker Flags.
  4. Add the -ObjC flag


Important Prerequisites

Let’s pause for some checks before we begin initializing the SDK:

Checkpoint 1: Preparing your App for iOS 10

App Transport Security (ATS), a default setting introduced with iOS 9 that mandates apps to make network connections only over TLS version 1.2 and later. Though InMobi is committed towards the adoption of HTTPS, the current setup requires our demand partners to support this change and be 100% compliant with all the requirements of ATS. While we work with our partners progressing towards a secure environment, to ensure ads work on iOS 9 and later versions, you need to follow these steps as a near-term fix:

Disable ATS (Recommended) - to ensure non-secure content from the partners work correctly in your updated apps. To disable ATS flag, add the following code snippet to your app's Info.plist.

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
</dict> 

Disable ATS with exceptions (Not Recommended) - if you plan to migrate towards ATS compliance. You can achieve so by allowing secure content from your domains by adding them on the exception list.

<key>NSAppTransportSecurity</key> 
<dict> 
    <key>NSAllowsArbitraryLoads</key> 
    <true/> 
    <key>NSExceptionDomains</key> 
    <dict> 
        <key>example.com</key> 
        <dict> 
            <key>NSIncludesSubdomains</key> 
            <true/> 
        </dict> 
    </dict> 
</dict>

Remember

Refrain from using InMobi domains and CDN in the exception list as it will result in errors during the runtime. 


Checkpoint 2: iOS 12 WiFi Settings

Apple has introduced privacy settings to access WiFi details from iOS 12 onwards. To boost monetization and relevant user experience, we encourage sharing WiFi details for targeted advertising.

  1. Enable ‘Access WiFi Information’ on your App ID.


     
  2. Enable access ‘Access WiFi Information’ for your target app from XCode capabilities.


     
  3. Ensure WiFi Access is added to your App.entitlements file.

Note

Please ask the user for location consent. Here is how to do that.


Initializing the SDK

Import the InMobi SDK header in your AppDelegate.h file:

Objective-C

@import InMobiSDK; 
/**Please do not remove the window property as it can lead to undefined behavior**/ 
@property (strong, nonatomic) UIWindow *window;

Swift

import InMobiSDK
/**Please do not remove the window property as it can lead to undefined behavior**/ 
var window: UIWindow?

Initialize the SDK in the didFinishLaunchingWithOptions method within the app delegate's.m file:

Objective-C

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    void (^completionBlock)(NSError*) = ^( NSError* _Nullable  error) { 
        if (error) { 
            NSLog(@"SDK Initialization Error - %@", error.description); 
        } 
        else { 
            NSLog(@"IM Media SDK successfully initialized"); 
        } 
    }; 
    [IMSdk setLogLevel:kIMSDKLogLevelDebug]; 
    [IMSdk initWithAccountID:kIMAccountID consentDictionary:@{IM_GDPR_CONSENT_AVAILABLE: @"true", IM_GDPR_CONSENT_IAB: @"<<consent in IAB format>>"} andCompletionHandler:completionBlock]; 
    return YES; 
} 

Swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        IMSdk.setLogLevel(IMSDKLogLevel.debug)
        IMSdk.initWithAccountID("accountID", consentDictionary: [IM_GDPR_CONSENT_AVAILABLE: "true", IM_GDPR_CONSENT_IAB: "<<consent in IAB format>>" ]) { (error) in
            if let error = error {
                print(error.localizedDescription)
            }
           
        }
        return true
    }

Let’s understand a few things here before you proceed:

What is a consentObject? - A consentObject is a dictionary representation of all kinds of consent provided by the publisher to the SDK. The key is mandatory if you wish to monetize traffic from EEA region. You can read further on GDPR regulations here.

Key Type Inference
gdpr_consent String A consent string is a series of numbers, which identifies the consent status of an Adtech Vendor.

The string must follow the IAB contracts as mentioned here.

gdpr_consent_available String "true": User has provided consent to collect and use data.

"false": User has not provided consent to collect and use data.

Any value other than “true” and “false” is invalid and will be treated as value not provided by user.

The key, gdpr_consent_available can be accessed via string constant IM_GDPR_CONSENT_IAB.

gdpr String Whether or not the request is subjected to GDPR regulations (0 = No, 1 = Yes), omission indicates Unknown.

Note 

As part of the General Data Protection Regulation (“GDPR”) publishers who collect data on their apps, are required to have a legal basis for collecting and processing the personal data of users in the European Economic Area (“EEA”). Please ensure that you obtain appropriate consent from the user before making ad requests to InMobi for Europe and indicate the same by following our recommended SDK implementation. Please do not pass any demographics information of a user; if you do not have user consent from such user in Europe.

A consentObject has to be provided in every session. SDK does not persist consent, it only keeps the consentObject in memory. If the app is relaunched, SDK will lose the consentObject. Within a session, a consentObject can be updated as below:

Objective-C

[IMSdk updateGDPRConsent:@{<Insert consentObject dictionary here>}];

Swift

IMSdk.updateGDPRConsent(<Insert consentObject dictionary here>)

Optimization

A. Pass the Location Information

Recommended

If your app collects location from the user, we recommend passing it up, as impressions with location signal have higher revenue potential. InMobi SDK will automatically pass the location signals if available in the app. If you use location in your app but would like to disable passing location signals to InMobi, then TURN OFF the “Location Automation” for your property on the InMobi dashboard.

Otherwise: You can set NSLocationWhenInUseUsageDescription flag (description for asking location permission) in your info.plist file.

Objective-C

//Using <CoreLocation/CoreLocation.h> fetch the coordinate
    self.locationMgr = [[CLLocationManager alloc] init];
    [self.locationMgr requestWhenInUseAuthorization];
    self.locationMgr.desiredAccuracy = kCLLocationAccuracyHundredMeters;
    self.locationMgr.delegate = self;
    [self.locationMgr startUpdatingLocation];
 
#pragma mark - CLLocationManagerDelegate
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations {
    CLLocation *clLocation = locations.lastObject;
    [IMSdk setLocation:clLocation];
    [self.locationMgr stopUpdatingLocation];
} 

Swift

"var locationMgr: CLLocationManager?

//Using CLLocationManagerDelegate fetch the coordinate
locationMgr = CLLocationManager()
locationMgr?.requestWhenInUseAuthorization()
locationMgr?.delegate = self
locationMgr?.startUpdatingLocation()

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let clLocation = locations.last {
            IMSdk.setLocation(clLocation)
    }
    locationMgr?.stopUpdatingLocation()
 }"

B. Pass Age and Gender information

Ensure that you have user consent to share this data. The following values are supported:

Age Gender
  • kIMSDKAgeGroupBelow18
  • kIMSDKAgeGroupBelow18And24
  • kIMSDKAgeGroupBetween25And29
  • kIMSDKAgeGroupBetween30And34
  • kIMSDKAgeGroupBetween35And44
  • kIMSDKAgeGroupBetween45And54
  • kIMSDKAgeGroupBetween55And65
  • kIMSDKAgeGroupAbove65
  • kIMSDKGenderMale
  • kIMSDKGenderFemale

Example:

Objective-C

[IMSdk setGender:kIMSDKGenderFemale];
[IMSdk setAgeGroup:kIMSDKAgeGroupBetween25And29];

Swift

IMSdk.setGender(.female)
IMSdk.setAgeGroup(.between25And29)

 

Audio Handling in WKWebView

For publishers running any audio or video media as the main content, we recommend listening to interruptions by observing AVAudioSessionInterruptionnotification posted by AVAudioSession. This will help preempt any content interruptions and help address user experience issues upfront. For more information read these Apple documents: Article 1, Article 2.

AVAudioSession Management

InMobi SDK uses iOS WKWebView to render HTML ads. As per Apple design, WKWebView does not respect the AVAudioSessionCategory set by the application, and also the OMSDK audio measurability remains inoperative. To have control over the HTML video ads, SDK manages the AVAudioSession.

The ad’s audio may mix in with the app’s audio. Hence, it is recommended to stop the app's audio when you present the fullscreen ads and resume it once the ad is dismissed.

From SDK 9.1.5 onwards, you can find a new API for handling AVAudiosSession. This feature is enabled by default.

+(void)shouldAutoManageAVAudioSession:(BOOL)value;

If you set it to YES, the SDK manages AVAudioSession automatically. When the ad is presented, the API sets AVAudioSession's category to AVAudioSessionCategoryAmbient and categoryOption to AVAudioSessionCategoryOptionMixWithOthers for Interstitial video ads. When the ad is dismissed, SDK resets the AVAusioSessionCategory and categoryOption to the original states.

This setting does not stop the ad audio from playing in the app. It mixes with the ad’s audio. Hence, it is recommended for you to stop the app’s audio when presenting the fullscreen ads and resume it after the ad is dismissed.

If you set it to NO, the SDK stops managing AVAudioSession during the HTML video playback lifecycle and OMSDK audio measurability may remain inoperative causing a revenue loss for the publisher.

For more information, please contact your respective partners.

You are all set now! Let’s now have a look at how you can set up different ad formats and begin monetizing. Ready?

On This Page

Last Updated on: 20 Jul, 2021

Preparing for iOS 14

Apple announced major IDFA-related changes on iOS 14 at WWDC 2020. Understandably, publishers have questions on its impact on app monetization. We have put together guides to give you a comprehensive view on the changes to ensure you have a seamless transition to the post iOS 14+ world.  

 
A. Comprehensive Guide on impact of iOS 14  

We have been talking to our partners to study the implications of iOS 14. The demand-side and supply-side guide explains our point of view on what to expect from the ecosystem at large and what we are planning for our roadmap to align our partners’ success. Click here. 


B. Integration Specifications and FAQs for Publishers 

We would recommend that you go through the iOS 14 specification document to understand details on integration and attribution requirements under the new guidelines from Apple. Click here 


C. SKAdNetwork IDs 

SKAdNetwork (SKAN) is a privacy-focused attribution mechanism developed by Apple. InMobi has made changes to the SDK and our programmatic pipes to support this new attribution flow. Publishers, however, have to add the list of SkAdNetwork IDprovided by each SSP (on behalf of the DSP partners) to their info.plist file to support attribution via SkAdNetwork. You can access the list of SKAN IDs with either of these two links:

  1. https://www.inmobi.com/skadnetworkids.xml
  2. https://www.inmobi.com/skadnetworkids.json

Note

*Please note that the SKAdNetwork list will be updated as more DSPs register and provide us their SKAN IDs. Your dedicated partner manager will reach out to you as and when the list is updated.  

On This Page

Last Updated on: 14 Oct, 2020

Banner Ads

Set up a Banner Ad

  1. Select BANNER AD to create a placement for ad type Banner.
  2. Once you create the banner placement, you will have the placement id.

Add the Banner Ad to your App

Creating a Banner Ad

The IMBanner is simply a UIView subclass displaying HTML ads. The InMobi SDK provides two mechanisms to implement a banner ad:

Programmatic Instantiation

1. Import the headers and declare a Banner instance in your ViewController.h file or import the frameworks and declare a Banner instance in your ViewController.swift file. Your ViewController header file should look like this:

Objective C

#import <UIKit/UIKit.h> 
@import InMobiSDK; 
@interface ViewController : UIViewController <IMBannerDelegate> 
@property (nonatomic, strong) IMBanner *banner; 
@end

Swift

import UIKit
import InMobiSDK
class ViewController: UIViewController, IMBannerDelegate {
    var banner: IMBanner?
}

2. Instantiate the banner object. Your ViewController.m file should look like this:

Objective C

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.banner = [[IMBanner alloc] initWithFrame: CGRectMake(0, 0, 320, 50) placementId:<placementId>]; 
    self.banner.delegate = self; 
    [self.view addSubview:self.banner]; 
    [self.banner load]; 
}

Swift

override func viewDidLoad() {
        super.viewDidLoad()
        banner = IMBanner.init(frame: CGRect(x: 0, y: 0, width: 320, height:
            50), placementId: <Insert your placement ID here>)
        banner?.delegate = self
        view.addSubview(banner!)
        banner?.load()
        // Use this API to enable or disable auto refresh
        banner?.shouldAutoRefresh(true)
        // Use this API to set a custom refresh interval on the banner
        banner?.refreshInterval = <refresh interval>
    }

By default, IMBanner refreshes after every 60 seconds. You can also set a custom refresh interval or turn off AutoRefresh to manually load ads. For both manual load and Auto Refresh, the minimum time interval between two successive ad loads should be 20 seconds.

Objective-C

// to turn off auto refresh set the below value to NO.
[self.banner shouldAutoRefresh:NO];

//to set custom refresh interval
[self.banner setRefreshInterval:40];

Swift

// to turn off auto refresh set the below value to NO.   banner?.shouldAutoRefresh(false).   //to set custom refresh interval banner?.refreshInterval = 40

3. If at any time you want to release the banner:

Objective C

[self.banner removeFromSuperview];
self.banner.delegate = nil;
self.banner = nil;

Swift

// perform the deinitialization
banner?.delegate = nil
banner = nil

4. For ad status callbacks, implement the delegate methods of IMBannerDelegate. We support the following callbacks:

Objective C

// Notifies that the ad is received with Meta info. 
- (void)banner:(IMBanner*)banner didReceiveWithMetaInfo:(IMAdMetaInfo*)info {
    NSLog(@"Banner Ad is received")
}
- (void)bannerDidFinishLoading:(IMBanner *)banner {
    NSLog(@"bannerDidFinishLoading");
}
- (void)banner:(IMBanner *)banner didFailToLoadWithError:(IMRequestStatus *)error {
    NSLog(@"banner failed to load ad");
    NSLog(@"Error : %@", error.description);
}
- (void)bannerWillPresentScreen:(IMBanner *)banner {
    NSLog(@"bannerWillPresentScreen");
}
- (void)bannerDidPresentScreen:(IMBanner *)banner {
    NSLog(@"bannerDidPresentScreen");
}
- (void)bannerWillDismissScreen:(IMBanner *)banner {
    NSLog(@"bannerWillDismissScreen");
}
- (void)bannerDidDismissScreen:(IMBanner *)banner {
    NSLog(@"bannerDidDismissScreen");
}
- (void)userWillLeaveApplicationFromBanner:(IMBanner *)banner {
    NSLog(@"userWillLeaveApplicationFromBanner");
}
-(void)banner:(IMBanner *)banner didInteractWithParams:(NSDictionary *)params{
    NSLog(@"bannerdidInteractWithParams"); 
}
-(void)banner:(IMBanner*)banner rewardActionCompletedWithRewards:(NSDictionary*)rewards{
    NSLog(@"rewardActionCompletedWithRewards");
}

Swift

// Notifies that the ad is received with Meta info.
public func banner(_ banner: IMBanner!, didReceiveWith info: IMAdMetaInfo!) {
    NSLog("Banner Ad is received")
}
public func bannerDidFinishLoading(_ banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func banner(_ banner: IMBanner!, didFailToLoadWithError error: 
IMRequestStatus!) {
    NSLog("[ViewController %@]", #function)
    NSLog("Banner ad failed to load with error %@", error)
}
public func banner(_ banner: IMBanner!, didInteractWithParams params: 
[AnyHashable : Any]!) {
    NSLog("[ViewController %@]", #function)
}
public func userWillLeaveApplication(from banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func bannerWillPresentScreen(_ banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func bannerDidPresentScreen(_ banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func bannerWillDismissScreen(_ banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func bannerDidDismissScreen(_ banner: IMBanner!) {
    NSLog("[ViewController %@]", #function)
}
public func banner(_ banner: IMBanner!, rewardActionCompletedWithRewards rewards: 
[AnyHashable : Any]!){
    NSLog("[ViewController %@]", #function)
}

You can use the following transitions while refreshing your banner object:

Objective C

  • UIViewAnimationTransitionNone
  • UIViewAnimationTransitionFlipFromLeft
  • UIViewAnimationTransitionFlipFromRight
  • UIViewAnimationTransitionCurlUp
  • UIViewAnimationTransitionCurlDown

Swift

  • none
  • flipFromLeft
  • flipFromRight
  • curlUp
  • curlDown

Objective C

self.banner.transitionAnimation = UIViewAnimationTransitionCurlUp;

Swift

banner?.transitionAnimation = .curlUp

Using Interface Builder

  1. Place the UIView in your ViewController’s view at the position where the ad should be displayed.
  2. Set the banner frame.
  3. Set the Class Identity of the UIView to IMBanner.
  4. In your ViewController header file, declare an IBOutlet instance of IMBanner.
  5. Set this as your outlet in your UIView(Banner) in the ViewController Scene in the Storyboard.
  6. In viewDidLoad(), enter the banner.placementId = <insert placement id>.

On This Page

Last Updated on: 04 Jan, 2021

Interstitial Ads

We support both static and video interstitial ads. The steps for setting up static and video interstitial ads are explained in the respective sections below.

Set up a Static Interstitial Ad

  1. To display an Interstitial ad, you need an interstitial placement ID.
  2. After adding your app, select INTERSTITIAL AD to create a placement for ad type Interstitial.
  3. Once you successfully create the placement, the placement ID is available.


Set up a Video Interstitial Ad

To create a video ad, you need to start creating an interstitial ad placement (as mentioned above). Once you have created an interstitial ad placement, you have controls on the InMobi portal to either run a mix of static and video ads or video only.

  1. Go to your interstitial placement and click Ad Controls.
  2. Enable video ads by selecting the first option in the list.
  3. Click on Video ad controls for enabling advanced features like skippable ads.

Add the Interstitial Ad to your App

Creating an Interstitial Ad

The IMInterstitial is simply a UIViewController subclass displaying full screen ads that respond to user touch.

Follow these steps to create the interstitial ad unit programmatically:

  1. Import the headers and declare an interstitial instance in your ViewController.h / ViewController.swift file. Your ViewController header file should look like this:

    Objective C

    #import  <UIKit/UIKit.h> 
    @import InMobiSDK; 
    @interface ViewController : UIViewController <IMInterstitialDelegate> 
    @property (nonatomic, strong) IMInterstitial *interstitial; 
    @end
    

    Swift

    import UIKit
    import InMobiSDK
    class ViewController: UIViewController, IMInterstitialDelegate {
        var interstitial: IMInterstitial?
    }
    	
  2. Instantiate the interstitial object. Your viewDidLoad method in ViewController.m file should look like this:
     

    Objective C

    -(void)viewDidLoad { 
        [super viewDidLoad]; 
        self.interstitial = [[IMInterstitial alloc] initWithPlacementId:<Insert your placement ID here>]; 
        self. interstitial.delegate = self; 
        [self.interstitial load]; 
    } 
    

    Swift

    override func viewDidLoad() { 
        super.viewDidLoad() 
        interstitial = IMInterstitial.init(placementId: <Insert your placement ID here>) 
        interstitial?.delegate = self 
        interstitial?.load() 
    } 
    
  3. For ad status callbacks, implement the delegate property of IMInterstitial. The following callbacks are supported:

    Objective C

    // Notifies that the ad is received with Meta info. 
    - (void)interstitial:(IMInterstitial *)interstitial didReceiveWithMetaInfo:(IMAdsMetaInfo*)metaInfo { 
        NSLog(@"interstitial didReceiveAdWithMetaInfo"); 
    } 
    - (void)interstitialDidFinishLoading:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidFinishLoading"); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didFailToLoadWithError:
    (IMRequestStatus *)error { 
        NSLog(@"Interstitial failed to load ad"); 
        NSLog(@"Error : %@",error.description); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didFailToPresentWithError:
    (IMRequestStatus *)error { 
        NSLog(@"Interstitial didFailToPresentWithError"); 
        NSLog(@"Error : %@",error.description); 
    } 
    - (void)interstitialWillPresent:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialWillPresent"); 
    } 
    - (void)interstitialDidPresent:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidPresent"); 
    } 
    - (void)interstitialWillDismiss:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialWillDismiss"); 
    } 
    - (void)interstitialDidDismiss:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidDismiss"); 
    } 
    - (void)userWillLeaveApplicationFromInterstitial:(IMInterstitial *)interstitial { 
        NSLog(@"userWillLeaveApplicationFromInterstitial"); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didInteractWithParams:
    (NSDictionary *)params { 
        NSLog(@"InterstitialDidInteractWithParams"); 
    }
    

    Swift

    //Notifies that the ad is received with Meta info. 
    public func interstitial(_ interstitial: IMInterstitial?, didReceiveWith metaInfo: IMAdMetaInfo?) { 
        NSLog("Interstitial ad is received with meta info %@", metaInfo) 
    } 
    public func interstitialDidFinishLoading(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didFailToLoadWithError error:
    IMRequestStatus!) { 
        NSLog("[ViewController %@]", #function) 
        NSLog("Interstitial ad failed to load with error %@", error) 
    } 
    public func interstitialWillPresent(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialDidPresent(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didFailToPresentWithError error:
    IMRequestStatus!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialWillDismiss(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialDidDismiss(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didInteractWithParams params:
    [AnyHashable : Any]!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func userWillLeaveApplication(from interstitial: IMInterstitial!){ 
        NSLog("[ViewController %@]", #function) 
    }
    
  4. To show the Interstitial Ad, use the following code:

    Objective C

    [self.interstitial showFromViewController:self];
    //[self.interstitial showFromViewController:self withAnimation:kIMInterstitialAnimationTypeCoverVertical];
    
    

    Swift

    interstitial?.show(from: self)
    //interstitial?.show(from: self, with:.coverVertical)
    
    

Objective C

Here are the possible animation types:

  • kIMInterstitialAnimationTypeCoverVertical
  • kIMInterstitialAnimationTypeFlipHorizontal
  • KIMInterstitialAnimationTypeNone

Important:

  • Make sure that interstitialDidFinishLoading callback is received before making a call to showFromViewController. Otherwise, the error callback interstitial:didFailToPresentScreenWithError: will be given.
  • Every time an interstitial ad is shown and subsequently dismissed, you will need to invoke [self.interstitial load]; again. Without this, you won't be able to call showFromViewController again.

Swift

Here are the possible animation types:

  • coverVertical
  • flipHorizontal
  • None

Important:

  • Make sure that interstitialDidFinishLoading callback is recieved before making a call to show(from viewController: UIViewController!). Otherwise, the error callback interstitial(_ interstitial: IMInterstitial!, didFailToLoadWithError error: IMRequestStatus!) will be given.
  • Every time an interstitial ad is shown and subsequently dismissed, you will need to invoke interstitial?.load() again. Without this, you won't be able to call show(from viewController: UIViewController!) again.


InMobi Custom Frames

Supercharge the full-screen experience by making the most of your in-game assets like characters, themes, and interactions to introduce interstitial ads which look like an extension of your game design.


Getting Started with Custom Frames

In order to activate Custom Frames on your interstitial ads, integrate with InMobi Interstitial ads and activate “Custom Frames” while creating the Interstitial placement.

  1. Specify the device you want to target the ad, and then select the orientation of your interstitial ad.
  2. Upload a frame, or select one of the preset frames. Ensure that you comply with the “Custom Frame Specification” mentioned in the section below.
  3. Upload a close button, or select one of the preset close buttons. You can choose the placement of the close button at either the top left or top right corner.
  4. Change the creative size to fit the interstitial ad and modify the placement of the creative using the “Creative Ad Position” to fit the interstitial ad perfectly. Ensure that the creative fits into the inner container of the frame and does not spill out.


More Details

Understanding Device Size and Orientation

InMobi Custom Frames are tied to a particular device size and orientation. This is important because you upload, or select, a specific frame to go with the device size and orientation combination.

Note

  • If you have an app that is usable in both landscape and portrait modes, and you make interstitial ad calls in both modes, you must create two custom frame ad units, one for each landscape and portrait. InMobi will automatically pick the right template based on the ad request orientation.
  • If you use the same placement Id for phones and tablets, you must create separate custom frame ad units for phones and tablets to make sure you can serve interstitial units with custom frames across all devices.


Understanding InMobi Default Templates

If you have at least one InMobi Custom Frame, you will see a listing page containing different custom frames, along with their performance metrics. The first item is called InMobi Default. You cannot edit this template, nor can you pause or delete this unit.


InMobi Default templates are used in two cases:

  • When an incoming ad request and ad combination does not match any custom frame unit created.
  • When InMobi, through its optimization logic, detects that not using a custom frame might actually give better performance.
  • For example, there are certain creatives that will not work with custom frames. In this case, the InMobi Default template is used to make sure that InMobi can render these high eCPM creatives in your ad slot.

Note

You cannot turn off the InMobi Default template.


Custom Frame Specification

Please keep in mind the following when designing custom frames for your interstitial ads:

  • The ad will appear in a transparent area (called the 'inner container') inside the frame.
  • In the image above, the inner container is the section in blue.
  • The inner container must be a rectangular figure with the same aspect ratio as the interstitial ad slot. That is, 2:3 for a 320x480 slot, 8:5 for a 1280x800 slot, and so on.
  • The inner container must be a transparent area.
  • The inner container cannot be less than 70% of the interstitial size. This means that for a 320x480 interstitial slot, the inner container should not be less than 224x336.
  • The inner edges of the frame must not be cluttered. That is, it should not disrupt the inner ad area. Strict rectangular corners, or very slightly rounded corners are allowed.


Refer the table below for the sizes supported:

Device Orientaton Frame Size Inner Container Size
Smartphone 1 Portrait 320x480 (RGB, 72ppi) 240x360
Smartphone 1 Landscape 480x320 (RGB, 72ppi) 360x240
Smartphone 2 Portrait 320x568 (RGB, 72ppi) 250x444
Smartphone 2 568x320 (RGB, 72ppi) 444x250  
Tablet 1 Portrait 768x1024 (RGB, 72ppi) 576x768
Tablet 1 1024x768 (RGB, 72ppi) 768x576  
Tablet 2 Portrait 800x1280 (RGB, 72ppi) 600x960
Tablet 2 1280x800 (RGB, 72ppi) 960x600  


Create the close button on a transparent area with an aspect ratio of 1:1. The allowed sizes are 15x15 px or 40x40 px.

Note

  • Frames and Close buttons must be uploaded in PNG format.
  • Background color and translucency are added by the SDK.


A/B Testing

Experiment with custom frames for the same interstitial placement by creating multiple concepts (for example, different colors, different characters, with and without animation, and so on) and distributing exposure across these concepts.

  • When testing new concepts, limit exposure to them to ensure that the monetization potential of your property is not affected. To limit the number of ad impressions served on the new concepts, you can select the Limit Exposure check box.
  • Once you are sure of the performance of the concept, you can uncheck the Limit Exposure check box.

On This Page

Last Updated on: 14 Oct, 2020

Rewarded Video Ads

Set up a Rewarded Video Ad

After adding your app, select REWARDED VIDEO to create a placement for ad type Rewarded video.

Once you select the placement type as rewarded video, you will be presented with the following.

You can fill in the key value pair for reward details. SDK will provide this dictionary as a JSON string through a delegate method called interstitial:rewardActionCompletedWithRewards: when the video play has ended. You can also choose to handle these rewards completely at your end.


Add the Rewarded Video Ad to your App

Creating a Rewarded Video Ad

Rewarded Video ads use IMInterstitial Class. The IMInterstitial is simply a UIViewController subclass displaying full screen ads that respond to user touch.

Follow these steps to create the rewarded video ad unit programmatically:

  1. Import the headers and declare an interstitial instance in your ViewController.h / ViewController.swift file. Your ViewController header file should look like this:

    Objective C

    #import  <UIKit/UIKit.h> 
    @import InMobiSDK; 
    @interface ViewController : UIViewController <IMInterstitialDelegate> 
    @property (nonatomic, strong) IMInterstitial *interstitial; 
    @end
    

    Swift

    import UIKit 
    import InMobiSDK 
    class ViewController: UIViewController, IMInterstitialDelegate { 
        var interstitial: IMInterstitial? 
    }
    
  2. Instantiate the interstitial object. Create only one object per placement ID and reuse it for subsequent ad loads. Your viewDidLoad method in ViewController.m file should look like this:


    Objective C

    -(void)viewDidLoad { 
        [super viewDidLoad]; 
        self. interstitial = [[IMInterstitial alloc] initWithPlacementId:<Insert your placement ID here>]; 
        self. interstitial.delegate = self; 
        [self.interstitial load]; 
    }
    

    Swift

    override func viewDidLoad() { 
        super.viewDidLoad() 
        interstitial = IMInterstitial.init(placementId: <Insert your placement here.>) 
        interstitial?.delegate = self 
        interstitial?.load() 
    }
    
  3. For ad status callbacks, implement the delegate property of IMInterstitial. The following callbacks are supported:

    Objective C

    - (void)interstitialDidFinishLoading:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidFinishLoading"); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didFailToLoadWithError:
    (IMRequestStatus *)error { 
        NSLog(@"Interstitial failed to load ad"); 
        NSLog(@"Error : %@",error.description); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didFailToPresentWithError:
    (IMRequestStatus *)error { 
        NSLog(@"Interstitial didFailToPresentWithError"); 
        NSLog(@"Error : %@",error.description); 
    } 
    - (void)interstitialWillPresent:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialWillPresent"); 
    } 
    - (void)interstitialDidPresent:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidPresent"); 
    } 
    - (void)interstitialWillDismiss:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialWillDismiss"); 
    } 
    - (void)interstitialDidDismiss:(IMInterstitial *)interstitial { 
        NSLog(@"interstitialDidDismiss"); 
    } 
    - (void)userWillLeaveApplicationFromInterstitial:(IMInterstitial *)interstitial { 
        NSLog(@"userWillLeaveApplicationFromInterstitial"); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial rewardActionCompletedWithRewards:
    (NSDictionary *)rewards { 
        NSLog(@"rewardActionCompletedWithRewards"); 
    } 
    - (void)interstitial:(IMInterstitial *)interstitial didInteractWithParams:(NSDictionary *)params { 
        NSLog(@"InterstitialDidInteractWithParams"); 
    } 
    / * Not used for direct integration. Notifies the delegate that the ad server has returned an ad but assets are not yet available. */ 
    - (void)interstitialDidReceiveAd:(IMInterstitial *)interstitial { 
      NSLog(@"interstitialDidReceiveAd"); 
    }
    

    Swift

    /** 
    * Notifies the delegate that the ad server has returned an ad. Assets are not yet available. 
    * Please use interstitialDidFinishLoading: to receive a callback when assets are also available. 
    */ 
    public func interstitialDidReceiveAd(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialDidFinishLoading(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didFailToLoadWithError error: IMRequestStatus!) { 
        NSLog("[ViewController %@]", #function) 
        NSLog("Interstitial ad failed to load with error %@", error) 
    } 
    public func interstitialWillPresent(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialDidPresent(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didFailToPresentWithError error: IMRequestStatus!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialWillDismiss(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitialDidDismiss(_ interstitial: IMInterstitial!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, didInteractWithParams params: [AnyHashable : Any]!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func interstitial(_ interstitial: IMInterstitial!, rewardActionCompletedWithRewards rewards: [AnyHashable : Any]!) { 
        NSLog("[ViewController %@]", #function) 
    } 
    public func userWillLeaveApplication(from interstitial: IMInterstitial!){ 
        NSLog"[ViewController %@]", #function) 
    }
    
  4. To show the Interstitial ad, use the following code:
     

    Objective C

    [self.interstitial showFromViewController:self];
    //[self.interstitial showFromViewController:self withAnimation:kIMInterstitialAnimationTypeCoverVertical];
    

    Swift

    interstitial?.show(from: self)
    //interstitial?.show(from: self, with:.coverVertical)
    	

 

Objective C

Here are the possible animation types:

  • kIMInterstitialAnimationTypeCoverVertical
  • kIMInterstitialAnimationTypeFlipHorizontal
  • kIMInterstitialAnimationTypeNone


Important

  • Make sure that interstitialDidFinishLoading delegate is fired before making a call to showFromViewController. Otherwise, the error callback interstitial:didFailToPresentScreenWithError: will be fired. Keep listening to the interstitial states to call show only when the ad is fully loaded.
  • Every time an interstitial ad is shown and subsequently dismissed, you will need to invoke [self.interstitial load]; again. Without this, you won't be able to call showFromViewController again.
  • Implement the interstitial:rewardActionCompletedWithRewards: method of IMInterstitialDelegate to detect video completion. If you have specified rewards on the InMobi portal, you can access the JSON dictionary here.


Swift

Here are the possible animation types:

  • coverVertical
  • flipHorizontal
  • none


Important

  • Make sure that interstitialDidFinishLoading delegate is fired before making a call to show(from viewController: UIViewController!). Otherwise, the error callback interstitial(_ interstitial: IMInterstitial!, didFailToLoadWithError error: IMRequestStatus!) will be fired. Keep listening to the interstitial states to call show only when the ad is fully loaded.
  • Every time an interstitial ad is shown and subsequently dismissed, you will need to invoke interstitial?.load() again. Without this, you won't be able to call show(from viewController: UIViewController!) again.
  • Implement the interstitial(_ interstitial: IMInterstitial!, rewardActionCompletedWithRewards rewards: [AnyHashable : Any]!) method of IMInterstitialDelegate to detect video completion. If you have specified rewards on the InMobi portal, you can access the JSON dictionary here.

On This Page

Last Updated on: 14 Oct, 2020

Native Ads

InMobi Native Ads support both video and static ads. You can opt for In-Feed, Splash or Pre-Roll formats. The steps for creating a native ad placement are given below:

Set up a Native Ad

  1. Create a Native Content placement.
  2. In-Feed Video Ad Placement

    Select FEED as the Native Ad Layout. For In-Feed Video, select either of the aspect ratios 256:135 or 16:9. Both the aspect ratios will have default static native fallback enabled with similar aspect ratio.

  1. Static Feed Ad Placement

    Select FEED as the Native Ad Layout.


     
  2. Splash Video Ad Placement

    Select SPLASH as the Native Ad Layout.

Select the desired aspect ratio. The default value for the aspect ratio will be 9:16.

  1. Others (China only)

    Select Others as the Native Ad Layout.

  • Select aspect ratio 16:9. This will have default static native fallback enabled with similar aspect ratio.
  • A new sub field is added in Others layout called Native Layout Type. It has the following values: “Native Interstitial”, “Native Page”, “Native Banner”, “Native Focus”, “Native Lock Screen”, “Native Other”.
  • Default value will be Native Interstitial in Native layout type field.
     
  1. Pre-Roll Ad Integration

    Select Pre-roll as the Native Ad Layout. 

Native Ad APIs

The IMNative Class contains the following objects:

  • NSString* adTitle - Returns the title for the ad.
  • NSString* adDescription - Returns the description for the ad.
  • UIImage* adIcon - Returns icon image for the ad.
  • NSString* adCtaText - Returns click to action text for the ad.
  • NSString* adRating - Returns rating for the ad (optional).
  • NSURL* adLandingPageUrl - Returns landing URL for the ad.
  • BOOL isAppDownload - Returns whether the ad is for downloading an app.
  • NSString* customAdContent - This will have additional information (description, image URL, etc.), which can be used to create custom UI around the primary view of ad.

The IMNative Class supports the following functions:

  • -(UIView*)primaryViewOfWidth:(CGFloat)width - Returns a UIView of specified width. This is the main ad content in your native ad. It will return a view of the same aspect ratio that you selected on the InMobi dashboard while creating the native placement. All impression render events are also fired automatically when this primary view is displayed on the screen. 
  • If you have selected Feed Layout while creating your placement, specify width = 25 while fetching your primaryView. It will just show the AdChoices Icon and fire the ad render events. 
  • -(void)load - Function to load an ad into memory. 
  • -(BOOL)isReady - True implies that the ad is ready to be displayed. 
  • -(void)reportAdClickAndOpenLandingPage - This function fires the click events and opens the landing page. You need not open landing page on your own while using this function. 
  • -(void)recyclePrimaryView - Call this function whenever the ad goes out of the visible area on the screen. Also, call this before loading a native ad again on the same object. 

In-Feed Ad Integration

  1. Import the InMobi SDK header files.

    Objective-C

    #import <InMobiSDK/InMobiSDK.h>
    

    Swift

    import InMobiSDK
    
  2. Declare an ad position in your feed where you want to show ad. Example is to show ad at 4th position.

    Objective-C

    #define IM_AD_INSERTION_POSITION 4
    

    Swift

    let adInsertionPosition = 4
    
  3. Declare a native Ad instance in your ViewController.m.

    Objective-C

    @interface TableViewController () <IMNativeDelegate> 
    @property(nonatomic,strong) IMNative *InMobiNativeAd; 
    @end
    

    Swift

    class ViewController: UIViewController, IMNativeDelegate {
    var inMobiNativeAd: IMNative?
    
  4. Your final ViewDidLoad Code should look like:

    Objective-C

    - (void)viewDidLoad { 
        [super viewDidLoad]; 
        self.InMobiNativeAd = [[IMNative alloc] initWithPlacementId:<Insert InMobi  placement ID here>]; 
        self.InMobiNativeAd.delegate = self; 
        [self.InMobiNativeAd load]; 
        //Your app content 
    }
    

    Swift

    override func viewDidLoad() {
        super.viewDidLoad()
        inMobiNativeAd = IMNative(placementId: <Insert InMobi plc id> )
        inMobiNativeAd?.delegate = self
        inMobiNativeAd?.load()
        // Your app content 
    }
    
    	
  5. Implement IMNativeDelegate methods for the success callback. The success callback indicates that the ad is ready to be shown on the screen. Here you should add the InMobiNativeAd Object to your TableView's data source.

    Objective-C

    -(void)nativeDidFinishLoading:(IMNative*)native{
        [self.tableData insertObject:native atIndex:IM_AD_INSERTION_POSITION];
        [self.tableView reloadData];
        NSLog(@"Native Ad did finish loading");
    }
    
    

    Swift

    func nativeDidFinishLoading(_ native: IMNative!) {
         self.tableData.insert(native, at: IM_AD_INSERTION_POSITION)
         self.tableView.reloadData()
         NSLog("InMobi Native Did finished loading");
    }
    
    
    
  6. Rendering native ads and impression tracking

    You have successfully received a native ad when you get the callback nativeAdDidFinishLoading. The following example shows how to fetch the adView in your tableView delegate cellForRowAtIndexPath.

    Note

    Impression events will be fired only when the Native Ad's primary view is in visible area of the screen.

    Implement the below custom cell class using storyboard.


    Objective-C

    #import
    @interface InFeedTableCell : UITableViewCell
    @property (nonatomic, strong) IBOutlet UIImage *iconImage;
    @property (nonatomic, strong) IBOutlet UILabel *titleLabel;
    @property (nonatomic, strong) IBOutlet UILabel *subTitleLabel;
    @property (nonatomic, strong) IBOutlet UILabel *descriptionLabel;
    @property (nonatomic, strong) IBOutlet UILabel *ctaLabel;
    @property (nonatomic, strong) IBOutlet UIView *adView;
    @end
    
    

    Swift

    class InFeedTableViewCell: UITableViewCell {
        @IBOutlet var iconImage : UIImage?
        @IBOutlet var titleLabel : UILabel?
        @IBOutlet var subtitleLabel : UILabel?
        @IBOutlet var descriptionLabel : UILabel?
        @IBOutlet var ctaLabel : UILabel?
        @IBOutlet var adView : UIView?
    }
    
    
     

    Objective-C

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
        InFeedTableCell *cell = ( *)[tableView dequeueReusableCellWithIdentifier:@"InFeedTableCell"]; 
        id nativeAd = [self.tableData objectAtIndex:indexPath.row]; 
        if ([nativeAd isKindOfClass:[IMNative Class]]]) { 
            IMNative * currentNativeAd = nativeAd; 
            cell.iconImage = currentNativeAd.adIcon; 
            cell.titleLabel.text = currentNativeAd.adTitle; 
            cell.subTitleLabel.text = @"Sponsored"; 
            cell.descriptionLabel.text = currentNativeAd.adDescription; 
            cell.ctaLabel.text = currentNativeAd.adCtaText; 
            //Calculate your feed's primaryImageViewWidth and use it to fetch and 
            Ad Primary view of same width. 
            UIView* = [currentNativeAd 
                       primaryViewOfWidth:primaryImageViewWidth]; 
            //Set the frame of Ad Primary View same as that of your feed's Primary View 
            cell.adView = adView; 
            UITapGestureRecognizer *singleTapAndOpenLandingPage = 
            [[UITapGestureRecognizer alloc] initWithTarget:currentNativeAd 
    
        action:@selector(reportAdClickAndOpenLandingPage)]; 
            cell.ctaLabel.userInteractionEnabled = YES; 
            [cell.ctaLabel addGestureRecognizer:singleTapAndOpenLandingPage]; 
        } 
        else{ 
            //Your App’s TableCell implementation 
        } 
        return cell; 
    } 
    

    Swift

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
            let cell = (tableView.dequeueReusableCell(withIdentifier: "InFeedTableCell")! as! InFeedTableViewCell)
    
            if let currentNativeAd = self.tableData?[indexPath.row] as? IMNative {
    
                    cell.iconImageView.image! = currentNativeAd.adIcon
    
                    cell.titleLabel!.text! = currentNativeAd.adTitle
    
                    cell.subtitleLabel?.text! = "Sponsored"
    
                    cell.descriptionLabel.text! = currentNativeAd.adDescription
    
                cell.ctaLabel?.text! = currentNativeAd.adCtaText
    
                    //Calculate your feed’s primaryImageViewWidth and use it to fetch and Ad Primary view of same width.
    
                    if let adPrimaryViewOfCorrectWidth =
                        currentNativeAd.primaryView(ofWidth: primaryImageViewWidth) {
                        cell.addSubview(adPrimaryViewOfCorrectWidth)
                }
                   
    
                let singleTapAndOpenLandingPage = UITapGestureRecognizer(target:currentNativeAd, action: #selector(self.reportAdClickAndOpenLandingPage))
    
                cell.ctaLabel?.isUserInteractionEnabled = true
    
                cell.ctaLabel?.addGestureRecognizer(singleTapAndOpenLandingPage)
    
                }
    
            else {
    
                // Your app's Table Cell implementations
    
            }
    
            return cell
    
        }
    
    	
  7. You need to recycle the Native Ad's Primary view, every time your ad goes out of the screen area. This is to optimize memory usage as well as ensuring that the AdView does not conflict with your app’s native views. Call recyclePrimaryView method on the InMobiNativeAd object every time the ad goes out of the visible area. In a TableView, this can be called in the didEndDisplayingCell Method:

    Objective-C

    - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 
        id nativeAd = [self.tableData objectAtIndex:indexPath.row] 
        if([nativeAdself isKindOfClass:[IMNative Class]]){ 
            IMNative *currentNativeAd = nativeAd; 
            [currentNativeAd recyclePrimaryView]; 
        } 
    }
    

    Swift

     func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
            if (tableData?[indexPath.row] as? UIView) != nil {
                inMobiNativeAd?.recyclePrimaryView()
            }
        }
    
    	

     

    Note

    After calling the recyclePrimaryView, if you want to add the view again on the screen, you must fetch it from [self.InMobiNativeAd primaryViewOfWidth:<custom width="">]</custom> as the previous view would have been recycled. If you have added it in the cellForRowAtIndexPath delegate (as mentioned in step 8), you don’t have to do anything here.
     

  8. Refreshing the ad - You will need to refresh the ad at various points to optimize ad exposure to your users. To refresh the ad, you will need to call the following functions in the same order.
     

    Objective-C

    -(void)refreshInMobiStrandAd { 
       [self.tableData removeObject:self.InMobiNativeAd]; 
       [self.tableView reloadData]; 
       [self.InMobiNativeAd recyclePrimaryView]; 
       self.InMobiNativeAd = [[IMNative alloc] initWithPlacementId:<Insert InMobi placement ID here>]; 
       self.InMobiNativeAd.delegate = self; 
       [self.InMobiNativeAd load]; 
    }
    

    Swift

    func refreshInMobiStrandAd() {
            tableData = tableData?.filter({ (obj) -> Bool in
                if obj is IMNative {
                    return false
                }
                return true
            })
            tableView.reloadData()
            inMobiNativeAd?.recyclePrimaryView()
            inMobiNativeAd = IMNative(placementId: )
            inMobiNativeAd?.delegate = self
            inMobiNativeAd?.load()
        }
    
    	

    It is important to remove the IMNative object from your tableData and destroy the current ad object. Then you need to create a new object and call load on it. Also, you should recycle the Primary View before destroying your existing object. 
  9. Handling Orientation Change - You will need to calculate the new width for Ad Primary View on orientation change and call the [self.InMobiNativeAd primaryViewOfWidth:<custom width="">]</custom> method again to replace the current Ad Primary View with the new view.
  10. You should set the InMobiNativeAd object and its delegate to nil in the dealloc method of your ViewController class. Do ensure you recycle the view before deallocating to remove all references to the adView.

    Objective-C

    -(void)dealloc {
        [self.InMobiNativeAd recyclePrimaryView];
        self.InMobiNativeAd.delegate = nil;
        self.InMobiNativeAd = nil;
    }
    
    

    Swift

    deinit {
            inMobiNativeAd?.recyclePrimaryView()
            inMobiNativeAd?.delegate = nil
            inMobiNativeAd = nil
        }
    	

Splash Ad Integration

  1. Splash experience can be implemented using the same IMNative Class.
  2. You should use self.InMobiNativeAd.isReady function to determine if the ad is ready to be shown. Sometimes, your main thread may be occupied and hence you may not receive nativeDidFinishLoading in time. Hence, it is better to proactively check if the ad is ready just after your cut-off time has elapsed.
  3. IMPORTANT: You should NOT dismiss the ad if the second screen of the ad is in display. You can check this in the nativeWillPresentScreen and not dismiss the ad if this delegate is fired. Sample implementation is as follows:

    Objective-C

    @property(nonatomic,strong) bool *isSecondScreenDisplayed;// Use this to check if second screen has to be shown or not
    -(void)nativeWillPresentScreen:(IMNative*)native{
        NSLog(@"Native Ad will present screen");
        isSecondScreenDisplayed = YES;
    }
    
    

    Swift

     var isSecondScreenDisplayed: Bool = false// Use this to check if second screen has to be shown or not
        func nativeWillPresentScreen(_ native: IMNative) {
            print("Native Ad will present screen")
            isSecondScreenDisplayed = true
        }
    	
  4. You should recycle the Primary View before dismissing the ad. This can be implemented as follows:

    Objective-C

    @property (nonatomic, strong) UIView* SplashAdView; // Use this view to check for visibility of splash screen
    -(void)dismissAd{
        if(isSecondScreenDisplayed){
            NSLog(@"DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED");
        }
        else{
            self.SplashAdView.hidden = true;
            [self.InMobiNativeAd recyclePrimaryView];
            self.InMobiNativeAd = nil;
        }
    }
    
    

    Swift

    var splashAdView: UIView? // Use this to check visibility of second screen
        func dismissAd() {
            if isSecondScreenDisplayed {
                print("DO NOT DISMISS THE AD WHILE THE SCREEN IS BEING DISPLAYED")
            }
            else {
                splashAdView?.isHidden = true
                inMobiNativeAd?.recyclePrimaryView()
                inMobiNativeAd = nil
            }
        }
    	

Pre-Roll Ad Integration

  1. Pre-Roll Video experience can be implemented using the same IMNative Class. You will need to dismiss the ad view in the following delegate:

    Objective-C

    -(void)nativeDidFinishPlayingMedia:(IMNative *)native{
        [self dismissAd];
    }
    
    

    Swift

    func nativeDidFinishPlayingMedia(_ native: IMNative) {
            self.dismissAd()
        }
    	
  2. The Pre-Roll ad can be dismissed as follows:

    Objective-C

    @property (nonatomic, strong) UIView* PrerollAdView; //Use this to store the primaryView returned by the IMNative instance.
    -(void)dismissAd{
        self.PrerollAdView.hidden = true;
        [self.InMobiNativeAd recyclePrimaryView];
        self.InMobiNativeAd = nil;
    }
    

    Swift

     var prerollAdView: UIView? // Use this to store the primaryView returned by the IMNative instance.
     func dismissAd() {
            prerollAdView?.isHidden = true
            inMobiNativeAd?.recyclePrimaryView()
            inMobiNativeAd = nil
        }
    
    	

Advanced Settings

You can perform the following steps to get additional callbacks. Implement the following delegate methods in your ViewController.m file:

Objective-C

/*Indicates that the naive has received the ad markup. */
-(void)nativeAdIsAvailable:(IMNative *)native {
    NSLog(@"nativeAdIsAvailable");
}
-(void)nativeDidFinishLoading:(IMNative*)native{
    NSLog(@"Native Ad load Successful"); // Ad is ready to be displayed
}
-(void)native:(IMNative*)native didFailToLoadWithError:(IMRequestStatus*)error{
    NSLog(@"Native Ad load Failed"); // No Fill or error
}
-(void)nativeWillPresentScreen:(IMNative*)native{
    NSLog(@"Native Ad will present screen"); //Full Screen experience is about to be presented
}
-(void)nativeDidPresentScreen:(IMNative*)native{
    NSLog(@"Native Ad did present screen"); //Full Screen experience has been presented
}
-(void)nativeWillDismissScreen:(IMNative*)native{
    NSLog(@"Native Ad will dismiss screen"); //Full Screen experience is going to be dismissed
}
-(void)nativeDidDismissScreen:(IMNative*)native{
    NSLog(@"Native Ad did dismiss screen"); //Full Screen experience has been dismissed
}
-(void)userWillLeaveApplicationFromNative:(IMNative*)native{
    NSLog(@"User leave"); //User is about to leave the app on clicking the ad
}
-(void)native:(IMNative *)native didInteractWithParams:(NSDictionary *)params{
    NSLog(@"User clicked"); // Called when the user clicks on the ad.
}
-(void)nativeAdImpressed:(IMNative *)native{
    NSLog(@"User viewed the ad"); // Called when impression event is fired.
}
-(void)nativeDidFinishPlayingMedia:(IMNative*)native{
    NSLog(@"The Video has finished playing"); // Called when the video has finished playing. Used for preroll use-case
}
-(void)userDidSkipPlayingMediaFromNative:(IMNative*) native {
    NSLog(@"User has skipped playing media"); // Called when the user has opted to skip the media being shown.
}
-(void)native:(IMNative*)native adAudioStateChanged:(BOOL)audioStateMuted {
    if (audioStateMuted) {
        NSLog(@"Inline video-ad audio state changed to mute");
    } 
    else {
        NSLog(@"Inline video-ad audio state changed to unmute");
    }
    //This is called when inline video audio state changes.
}

Swift

func nativeDidFinishLoading(_ native: IMNative) {
        print("Native Ad load Successful") // Ad is ready to be displayed
    }
    func native(_ native: IMNative, didFailToLoadWithError error: IMRequestStatus) {
        print("Native Ad load Failed") // No Fill or error
    }
    func nativeWillPresentScreen(_ native: IMNative) {
        print("Native Ad will present screen") //Full Screen experience is about to be presented
    }
    func nativeDidPresentScreen(_ native: IMNative) {
        print("Native Ad did present screen") //Full Screen experience has been presented
     }
    func nativeWillDismissScreen(_ native: IMNative) {
        print("Native Ad will dismiss screen") //Full Screen experience is going to be dismissed
    }
    func nativeDidDismissScreen(_ native: IMNative) {
        print("Native Ad did dismiss screen") //Full Screen experience has been dismissed
    }
    func userWillLeaveApplication(from native: IMNative) {
        print("User leave") //User is about to leave the app on clicking the ad
    }
    private func native(native: IMNative, didInteractWithParams params: [NSObject : AnyObject]) {
        print("User clicked") // Called when the user clicks on the ad.
    }
    func nativeAdImpressed(_ native: IMNative) {
        print("User viewed the ad") // Called when impression event is fired.
    }
    func nativeDidFinishPlayingMedia(_ native: IMNative) {
        print("The Video has finished playing") // Called when the video has finished playing. Used for preroll use-case
    }
    func userDidSkipPlayingMedia(from native: IMNative) {
        print("User has skipped playing the media") // Called when the user has opted to skip the media being shown.
    }
    func native(_ native: IMNative, adAudioStateChanged audioStateMuted: Bool) {
        if (audioStateMuted) {
            print("Inline state changed to mute")
        }
        else {
            print("Inline state changed to unmute")
        }
    }


Implementing Backfill

InMobi's SDK can run both HTML and native units against your native placement. You can run the following ad sizes depending on the real-estate reserved for your native placement.

  • 320x50 HTML Banner
  • 300x250 HTML Banner
  • 320x480 HTML Full screen Banner
  • 320x568 HTML Full screen Banner

To switch this on, you need to reach out to your respective partner manager with the preferred backfill size. Also, you will need to handle this in your code as follows:

Objective-C

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    InFeedTableCell *cell = (InFeedTableCell *)[tableView
                                                dequeueReusableCellWithIdentifier:@"InFeedTableCell"];
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"InFeedTableCell"
                                                 owner:self options:nil];
    cell = [nib objectAtIndex:0];
    id slide = [self.tableData objectAtIndex:indexPath.row];
    if ([self isAdAtIndexPath:indexPath]) {
        IMNative *currentNativeAd = slide;
        NSString *customJSONstring = currentNativeAd.customAdContent;
        NSData *data = [customJSONstring dataUsingEncoding:NSUTF8StringEncoding];
        NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        BOOL isBackFillBanner = [[jsonDict objectForKey:@"isHTMLResponse"] boolValue];
        if (isBackFillBanner) {
            IMNative * currentNativeAd = slide;
            //Depending on the selected backfill size, provide accurate width below
            UIView* AdPrimaryViewOfCorrectWidth = [currentNativeAd primaryViewOfWidth:250];
            AdPrimaryViewOfCorrectWidth.frame = CGRectMake((_screenWidth-300)/2, 0, 300, 250);
            [cell addSubview:AdPrimaryViewOfCorrectWidth];
        }
        else
        {
            //continue with the current native implementation
            IMNative * currentNativeAd = slide;
            cell.iconImageView.image = currentNativeAd.adIcon;
            cell.titleLabel.text = currentNativeAd.adTitle;
            cell.subTitleLabel.text = @"Sponsored";
            cell.descriptionLabel.text = currentNativeAd.adDescription;
            cell.ctaLabel.text = currentNativeAd.adCtaText;
            //Calculate your feed's primaryImageViewWidth and use it to fetch and Ad Primary view of same width.
            UIView* AdPrimaryViewOfCorrectWidth = [currentNativeAd primaryViewOfWidth:primaryImageViewWidth];
            //Set the frame of Ad Primary View same as that of your feed's Primary View
            AdPrimaryViewOfCorrectWidth.frame = primaryImageViewFrame;
            [cell addSubview:AdPrimaryViewOfCorrectWidth];
            UITapGestureRecognizer *singleTapAndOpenLandingPage =
            [[UITapGestureRecognizer alloc] initWithTarget:currentNativeAd
                                                    action:@selector(reportAdClickAndOpenLandingPage)];
            cell.ctaLabel.userInteractionEnabled = YES;
            [cell.ctaLabel addGestureRecognizer:singleTapAndOpenLandingPage];
        }
    }
    else {
        //Your App’s TableCell implementation
    }
    return cell;
}

Swift

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = (tableView.dequeueReusableCell(withIdentifier: "InFeedTableCell")! as! InFeedTableViewCell)
        if let currentNativeAd = self.tableData?[indexPath.row] as? IMNative {
            let customJSONstring = currentNativeAd.customAdContent
            if let data = customJSONstring?.data(using: .utf8) {
                do {
                    if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                        if let isBackFillBanner = json["isHTMLResponse"] as? Bool, isBackFillBanner {
                            //Depending on the selected backfill size, provide accurate width below
                            let adPrimaryViewOfCorrectWidth: UIView = currentNativeAd.primaryView(ofWidth: 250)
                            adPrimaryViewOfCorrectWidth.frame = CGRect(x: (_screenWidth-300)/2, y: 0, width: 300, height: 250)
                            cell.addSubview(adPrimaryViewOfCorrectWidth)
                           
                        } else {
                            //continue with the current native implementation
                            cell.iconImageView.image = currentNativeAd.adIcon
                            cell.titleLabel.text = currentNativeAd.adTitle
                            cell.subtitleLabel.text = "Sponsored"
                            cell.descriptionLabel.text = currentNativeAd.description
                            cell.ctaLabel?.text = currentNativeAd.adCtaText
                           
                            //Calculate your feed's primaryImageViewWidth and use it to fetch and Ad Primary view of same width.
                            let adPrimaryViewOfCorrectWidth: UIView = currentNativeAd.primaryView(ofWidth: primaryImageViewWidth)
                           
                            //Set the frame of Ad Primary View same as that of your feed's Primary View
                            let singleTapAndOpenLandingPage = UITapGestureRecognizer(target:currentNativeAd, action: #selector(self.reportAdClickAndOpenLandingPage))
                            cell.ctaLabel?.isUserInteractionEnabled = true
                            cell.ctaLabel?.addGestureRecognizer(singleTapAndOpenLandingPage)
                        }
                    }
                } catch let error as NSError {
                    print("Failed to load: \(error.localizedDescription)")
                }
            }
        }
        return cell    }

 

Note

  • To detect if the response is backfill, the customAdContent will contain the string isHTMLResponse.
  • Do NOT scale the width of the HTML banner response. For e.g. if you selected backfill of 300x250, make sure the provided width is hardcoded 250.
  • Do NOT add the CTA button in case of backfill response. The clicks will not be monetized in case you add this button alongside the ad.

On This Page

Last Updated on: 17 Feb, 2021

Testing and Troubleshooting

Retrieve the CreativeID

At times, there are rogue advertisers who escape all the ad quality checks and end up compromising the user experience on the app by showcasing either an irrelevant, distasteful or disrupting creative to the user. To combat such situations, you can retrieve the creativeID of the ad instance and report back to your InMobi point of contact with the encrypted creativeID. CreativeID is a property of IMBanner, IMInterstitial and IMNative object, which can be retrieve as follow:

Objective

- (void)bannerDidFinishLoading:(IMBanner*)banner { 
    NSString* creativeId = banner.creativeId;
}


Swift

public func bannerDidFinishLoading(_ banner: IMBanner!) {
    bannerAd.creativeId
}

Test the Integration

  1. Configure the test mode on InMobi portal.
  2. Go to Tools - Diagnostics and switch Test Mode to either Global ON or Selective ON.

If you are integrating an ad unit for the first time

Set Test Mode to Global ON.

If you want to selectively turn on test traffic for a set of devices.

You already have a prior version of the SDK integrated for this ad unit and therefore you should restrict your testing to only few devices.

Set Test Mode to Selective ON.

In the device section:

  1. In the Device ID box, type the device ID.
  2. In the Device Name box, set any name.
  3. Click Add Device to add the test device.

If you already have a device configured, you can select the device and test mode will be enabled.

Remember

You MUST turn off the test mode before going live or else your app will fail to monetize.

Now you are all set to get test ads.


Get the Device ID

The device id is basically the IDFA or IFA (Identifier for Advertising). To get device ID:

Objective

#import AdSupport 
NSString* deviceID = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];


Swift

import AdSupport 
let deviceId = ASIdentifierManager.shared().advertisingIdentifier.uuidString

Helpful Debug Information

  1. Set log level to debug: [IMSdk setLogLevel: kIMSDKLogLevelDebug]
  2. You will get feedback on the diagnostics tab on the ad unit and ad request and this can be particularly helpful during integration.


The important set of logs are documented in the following tables.

SDK Initialization

Scenario

Log Level

Logs

Publisher passed valid account id

Debug

InMobi SDK initialized with account id:

Publisher passed an invalid account Id

Error

Invalid account id passed to init. Please provide a valid account id.

Newer version of SDK is available

Debug

A newer version (ver. 9.0.0) of the InMobi SDK is available! You are currently on an older version (ver. 5.3.1). Download the latest InMobi SDK from http://www.inmobi.com/products/sdk/#downloads.

Ads Common

Scenario

Log Level

Logs

Ad requested when no network available

Error

Network not reachable currently. Please try again.

Ad requested when ad state is loading or available

Error

An ad load is already in progress. Please wait for the load to complete before requesting for another ad (Placement id : ).

Ad requested when ad is viewed by user

Error

An ad is currently being viewed by the user. Please wait for the user to close the ad before requesting for another ad (Placement id : ).


Messages for Ad Integrations

 Banner

Scenario

Log Level

Logs

Publisher created a banner without initializing the SDK

Error

Please initialize the SDK before creating a Banner ad

Publisher created a banner with an invalid/null placement id

Error

Please provide a valid placement id to create a Banner ad

Publisher called load on a banner from IB/xml with improper placement id

Error

Please provide a valid placement id to create a Banner ad

Publisher called load on a banner

Debug

Fetching a Banner ad for placement id: ()

Successfully fetched ad

Debug

Banner ad successfully fetched for placement id: ()

Failed to fetch the ad

Debug

Failed to fetch Banner ad for placement id: ( with error: )

Started loading the banner in a webview

Debug

Started loading Banner ad markup in the webview for placement id: ()

Banner successfully loaded in the webview

Debug

Successfully loaded Banner ad markup in the webview for placement id: ()

Failed to load banner in the webview

Debug

Failed to load the Banner markup in the webview for placement id: ()

Banner refresh is initiated

Debug

Initiating Banner refresh for placement id: ()


Interstitial

Scenario

Log Level

Logs

Publisher created a interstitial without initializing the SDK

Error

Please initialize the SDK before creating a interstitial ad

Publisher created a interstitial with an invalid placement id

Error

Please provide a valid placement id to create a interstitial ad

Publisher called load on an interstitial

Debug

Fetching an interstitial ad for placement id:

Successfully fetched ad

Debug

Interstitial ad successfully fetched for placement id:

Failed to fetch the ad

Error

Failed to fetch Interstitial ad for placement id: with error:

Started loading the interstitial in a webview

Debug

Started loading Interstitial ad markup in the webview for placement id:

Interstitial successfully loaded in the webview

Debug

Successfully loaded Interstitial ad markup in the webview for placement id:

Failed to load interstitial in the webview

Error

Failed to load the Interstitial markup in the webview for placement id:

Interstitial Ad displayed

Debug

Successfully displayed Interstitial for placement id:

Interstitial Ad dismissed

Debug

Interstitial ad dismissed for placement id:

Ad show before ready Show ad before it's ready

Error

Ad Load is not complete. Please wait for the Ad to be in a ready state before calling show

Full screen ad cannot be displayed without a view controller. Please pass a view controller to present the full screen ad.

Error

Full screen ad cannot be displayed without a view controller. Please pass a view controller to present the full screen ad.

Rewarded Video

Scenario

Log Level

Logs

Publisher created a interstitial without initializing the SDK

Error

Please initialize the SDK before creating a interstitial ad

Publisher created a interstitial with an invalid placement id

Error

Please provide a valid placement id to create a interstitial ad

Publisher called load on an interstitial

Debug

Fetching an interstitial ad for placement id:

Successfully fetched ad

Debug

Interstitial ad successfully fetched for placement id:

Failed to fetch the ad

Error

Failed to fetch Interstitial ad for placement id: with error:

Started loading the interstitial in a webview

Debug

Started loading Interstitial ad markup in the webview for placement id:

Interstitial successfully loaded in the webview

Debug

Successfully loaded Interstitial ad markup in the webview for placement id:

Failed to load interstitial in the webview

Error

Failed to load the Interstitial markup in the webview for placement id:

Interstitial Ad displayed

Debug

Successfully displayed Interstitial for placement id:

Interstitial Ad dismissed

Debug

Interstitial ad dismissed for placement id:

Ad show before ready Show ad before it's ready

Error

Ad Load is not complete. Please wait for the Ad to be in a ready state before calling show

Full screen ad cannot be displayed without a view controller. Please pass a view controller to present the full screen ad.

Error

Full screen ad cannot be displayed without a view controller. Please pass a view controller to present the full screen ad.

Native

Scenario

Log Level

Log Message

Publisher created a native ad without initializing the SDK

Error

Please initialize the SDK before creating a Native ad

Publisher created a native ad with an invalid placement id

Error

Please provide a valid placement id to create a native ad

Publisher called load on a native

Debug

Fetching a Native ad for placement id:

Ad is successfully fetched from server

Debug

Native ad successfully fetched for placement id:

Failed to fetch the ad

Error

Failed to fetch Native ad for placement id : with error : 

On This Page

Last Updated on: 21 Sep, 2020