inmobi-ad-tracker-iat | iOS

Prerequisites

  • The latest version of InMobi Mediation SDK supports iOS 9 or higher. Also, this version of iOS Mediation SDK requires XCode 10.2 or higher.
  • We recommend to call all InMobi Mediation APIs on main thread.

Step 1: Integrating the SDK

  • Step 1.1: Download the InMobi SDK

    a. Download the latest InMobi SDK below. We also provide the option to use CocoaPods!

    Download the InMobi iOS Mediation SDK here.

    The SDK bundle contains all media adapters that we support. Prune the downloaded folder to retain the media adapters you need.


    b. CocoaPods (Optional)

    In the same directory as your YOUR_PROJECT.xcodeproj, create an empty file named Podfile and copy and paste the following:

              platform :ios, '9.0'
              target 'APP_NAME' do
                    pod 'InMobiMediationSDK'
              end
    		

    Ensure your project has been closed. Using the terminal, navigate to the directory containing the Podfile and run the command: pod install. Once the installation finishes, use YOUR_PROJECT.xcworkspace to access your project moving forward.

    Inside the xcworkspace there should be a Pods directory included with an ios-sdk-pod sub-directory.

    Warning: Please remove all older versions of the InMobi SDK (8.X.X and older) and all older versions of the AerServ SDK. Otherwise, your code will not compile! Please reach out to your account manager if you have any questions. If you are using CocoaPods, be sure to remove the 'aerserv-ios-sdk' pod from your podfile and only use the 'inmobi-ios-sdk' pod.

  • Step 1.2: Add the Required Libraries

    Add the following framework into your project from the InMobi SDK download:

    • InMobiSDK.framework
    • InMobiMediationSDK.framework

    All supported mediation partner libraries and headers are present in the network-support folder, please add the mediation partners as per choice.

    Note: When using any mediation through the InMobi SDK, it is highly recommended that you use the framework that is provided along with the InMobi SDK download. These versions have been tested by our team and using any other version may not be officially supported.

  • Step 1.3: General Settings

    Under the General tab within your project's target, you'll need to add the following settings:

    • Select all desired Device Orientation inside 'Deployment Info'.
    • Add the following dependencies to Linked Frameworks and Libraries:
      • WebKit.framework
      • libsqlite3.0.tbd
      • libz.tbd
  • Step 1.4: Create a bridging header (Swift Only)

    You will need to create a bridging header if your application is built with Swift. The bridging header exposes the Objective-C implementation to Swift. To create the bridging header, you'll need to do the following:

    1. Create a new header file, InMobiSDK-Bridging-Header.h.
    2. Add the following entry to the Bridging Header:
      #import <InMobiSDK/InMobiSDK.h>
      			
    3. Add the newly created header file's path to the target'sBuild Setting->Linking->Objective-C Bridging Header

  • Step 1.5: Build Settings

    Add the following flags to the target's Build Setting->Linking->Other Flag:

    • -ObjC

  • Step 1.6: Info.plist

    You will need to add the following entries into your info.plist:

    <key>LSApplicationQueriesSchemes</key>
    <array>
    <string>fb</string>
    <string>instagram</string>
    <string>tumblr</string>
    <string>twitter</string>
    </array>
    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Location is used to help target content to your general area</string>
    <key>NSCalendarsUsageDescription</key>
    <string>Some ad content may create a calendar event.</string>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>Some ad content may require access to the photo library.</string>
    <key>NSCameraUsageDescription</key>
    <string>Some ad content may access camera to take picture.</string>
    <key>NSMotionUsageDescription</key>
    <string>Some ad content may require access to accelerometer for interactive ad experience.</string>
    		

    Note: For iOS 9 and above, you will need to disable App Transport Security (ATS).
    We recommend that you disable ATS to improve fill rates. Should you choose to leave ATS enabled, your monetization may get affected! Please refer here for more detail.
    Please reach out to your account manager for any further questions you may have.

Step 2: Initializing the InMobi SDK

You must initialize our SDK before loading any ads. Initializing InMobi SDK will update server-side configurations and additionally initialize any mediated ad sources.

Within the AerServ + InMobi dashboard, click on the inventory tab and edit the specific application that is being integrated. There will be an App ID associated with that application. Use that App ID to call InMobi SDK's initializeWithAppID:. Suggested place to kick off the initialization process is in the application's AppDelegate inside the application:didFinishLaunchingWithOptions: method.

It is recommended that you initialize the InMobi SDK as early as possible and 10 seconds before making your first ad request.

  • Objective-C
    /*!
         * Looks into the supplied app id and will run pre-initialization for any mediation partner sources that requires an extra setup phase.
         *
         * @param appId a string of the app id
         * @param error error object to be populated if initialization is not completed
    */
    + (void)initializeWithAppID:(NSString*)appId andError:(NSError * _Nullable * _Nonnull)error;
    /**
         * Initialize the sdk. This must be called before any other API for the SDK is used.
         * @param appId App id obtained from the Aerserv portal.
         * @param consentDictionary InMobi relies on the publishers to obtain explicit consent from users for continuing business activities in EU as per GDPR . Consent dictionary allows publishers to indicate consent status as obtained from the users for InMobi services to function appropriately.
         * It has Three optional keys:"gdpr", IM_GDPR_CONSENT_AVAILABLE, IM_GDPR_CONSENT_IAB
         * "gdpr"(String): Whether or not the request is subjected to GDPR regulations (0 = No, 1 = Yes), omission indicates Unknown.
         * IM_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.
         * IM_GDPR_CONSENT_IAB(string): Key to send the IAB consent string.
         * @param error error object to be populated if initialization is not completed
     */
     + (void)initializeWithAppID:(NSString*)appId andUserConsent:(nullable NSDictionary *)consentDictionary andError:(NSError     * _Nullable     * _Nonnull)error;
    /*!
     	* updates the user consent for a session of the app
     	* @param consentDictionary consent dictionary allows publishers to provide its consent to collect user data and use it.
     	* It has Three optional keys:"gdpr", IM_GDPR_CONSENT_AVAILABLE, IM_GDPR_CONSENT_IAB
     	* "gdpr"(String): Whether or not the request is subjected to GDPR regulations (0 = No, 1 = Yes), omission indicates Unknown.
     	* IM_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.
     	* IM_GDPR_CONSENT_IAB(string): Key to send the IAB consent string.
     	*/
    + (void)setGDPRWithUserConsent:(NSDictionary *)consentDictionary;
    		

How to obtain the app ID:

  • Log in to the AerServ + InMobi platform.
  • Go to the 'Inventory' tab in the top navigation bar.
  • Click the 'Edit' icon next to the app whose ID you wish to obtain.
  • You will find the app ID at the very top of the page.

To set or update the General Data Protection Regulation (GDPR) user consent flag, call InMobi SDK’s +setGDPRWithUserConsent: method. Pass a dictionary with InMobi provided keys:

{	IM_GDPR_CONSENT_AVAILABLE : “true”,
		IM_GDPR_CONSENT_IAB : <IAB STRING>
}
	

If user consent was granted and if user consent was denied or unknown change IM_GDPR_CONSENT_AVAILABLE value to “FALSE” in the above dictionary.

To have the GDPR user consent flag to be set before an ad request, call +setGDPRWithUserConsent: before calling -loadAd. The values passed into +setGDPRWithUserConsent: will be stored in the NSUserDefaults, persisting the chosen consent. Thus, it is not necessary to reset the user consent value prior to each ad request; the value set is applicable for all subsequent requests until that value is reset.

An example would be:

  • Objective-C
    NSDictionary *consentDictionary =   @{IM_GDPR_CONSENT_AVAILABLE: @"true",IM_GDPR_CONSENT_IAB: @"iabConsentString"};
    [AerServSDK initializeWithAppID:@"APP_ID" andUserConsent:consentDictionary andError:&error];
    if(error) {
        NSLog(@"**** ERROR: Failed to initialize with error %@. ****",error.description);
    }
    // or
    [AerServSDK initializeWithAppID:@"APP_ID" andError:&error];
    if(error) {
        NSLog(@"**** ERROR: Failed to initialize with error %@. ****",error.description);
    }
    [AerServSDK setGDPRWithUserConsent:consentDictionary];
    		
  • Swift
    let consentDictionary : [String:String] = [IM_GDPR_CONSENT_AVAILABLE : "true", IM_GDPR_CONSENT_IAB : "iabConsentString"]
    AerServSDK.initialize(withAppID: "APP_ID", andUserConsent: consentDictionary, andError: &error)
    if((error) != nil) {
        print("**** ERROR: Failed to initialize with error %@. ****",error?.description as Any);
    }
    // or
    AerServSDK.initialize(withAppID: "APP_ID", andError: &error)
    if((error) != nil) {
        print("**** ERROR: Failed to initialize with error %@. ****",error?.description as Any);
    }
    AerServSDK.setGDPRWithUserConsent(consentDictionary)
    		

Mediation Disclaimer: Please be advised that although we are GDPR compliant, we currently have no way to send GDPR compliance as well as user consent to our mediated SDK partners. Compliance responsibility and request handling will solely depend on the SDK mediated partner. Please contact your mediated partners to avoid any issues and/or complications.

Step 3: Displaying Banner Ads

  • Step 3.1: Loading and Showing Banners

    • Create an ASAdView object by passing in a placement setup on the AerServ + InMobi dashboard as well as the banner's size. Refer to ASAdView.h for InMobi SDK's predefined sizes.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController()
        @property(nonatomic, strong) ASAdView* asAdView;
        @end
        @implementation ViewController
        - (void)loadBannerAd {
          // Create the AerServ banner object
          self.asAdView = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];   
        }
        @end
        				
      • Swift
        class ViewController: UIViewController, {
          var asAdView: ASAdView?
          func loadBannerAd() {
            // Create the AerServ banner object
            asAdView? = ASAdView(placementID: "1024876", andAdSize: ASBannerSize)
          }
        }
        				

    • Add the ASAdView object to your application's view.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController()
        @property(nonatomic, strong) ASAdView* asAdView;
        @end
        @implementation ViewController
        - (void)loadBannerAd {
          // Create the AerServ banner object
          self.asAdview = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];
          // Add banner to a parent view
          [self.view addSubview:asAdView];
        }
        @end
        				
      • Swift
        class ViewController: UIViewController {
          var asAdView: ASAdView?
          func loadBannerAd() {
            // Create the AerServ banner object
            asAdView? = ASAdView(placementID: "1024876", andAdSize: ASBannerSize)
            // Add banner to a parent view
            view.addSubview(asAdView!)
          }
        }
        				
    • In the view controller that the ASAdView object is added to, make sure that the view controller adheres to the ASAdViewDelegate protocol. Additionally, add the callback -viewControllerForPresentingModalView that will return itself.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController() <ASAdViewDelegate>
        @property(nonatomic, strong) ASAdView* asAdView;
        @end
        @implementation ViewController
        - (void)loadBannerAd {
          // Create the AerServ banner object
          self.asAdview = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];
          self.asAdview.delegate = self;
          // Add banner to a parent view
          [self.view addSubview:asAdView];
        }
        #pragma mark - AerServ Interstitial Callbacks 
        - (UIViewController*)viewControllerForPresentingModalView {
          return self;
        }
        @end
        				
      • Swift
        class ViewController: UIViewController, ASAdViewDelegate {
          var asAdView: ASAdView?
          func loadBannerAd() {
            // Create the AerServ banner object
            asAdView? = ASAdView(placementID: "1024876", andAdSize: ASBannerSize)
            asAdView?.delegate = self
            // Add banner to a parent view
            view.addSubview(asAdView!)
          }
          //MARK: AerServ Banner Callback
          func viewControllerForPresentingModalView() -> UIViewController! {
            return self  
          }
        }
        				
    • Lastly, kick off the ad request by loading the ad.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController() <ASAdViewDelegate>
        @property(nonatomic, strong) ASAdView* asAdView;
        @end
        @implementation ViewController
        - (void)loadBannerAd {
          // Create the AerServ banner object
          self.asAdview = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];
          self.asAdview.delegate = self;
          // Add banner to a parent view
          [self.view addSubview:asAdView];
          // Use loadAd to make a request to the AerServ ad server for an ad
          [self.asAdView loadAd];
        }
        #pragma mark - AerServ Banner Callbacks
        - (UIViewController*)viewControllerForPresentingModalView {
          return self;
        }
        @end
        				
      • Swift
        class ViewController: UIViewController, ASAdViewDelegate {
          var asAdView: ASAdView?
          func loadBannerAd() {
            // Create the AerServ banner object
            asAdView? = ASAdView(placementID: "1024876", andAdSize: ASBannerSize)
            asAdView?.delegate = self
            // Add banner to a parent view
            view.addSubview(asAdView!)
            // Use loadAd to make a request to the AerServ ad server for an ad
            asAdView?.loadAd()
          }
          //MARK: AerServ Banner Callback
          func viewControllerForPresentingModalView() -> UIViewController! {
            return self  
          }
        }
        				

  • Step 3.2: Optional Banner Callbacks

    You can additionally assign a delegate to listen for the banner's callback events. A few of the callbacks that can be listened to are:

    • Objective-C
      #pragma mark - AerServ Banner Callbacks
      - (void)adViewDidLoadAd:(ASAdView*)adView { }
      - (void)adViewDidPreloadAd:(ASAdView*)adView { }
      - (void)adViewDidFailToLoadAd:(ASAdView*)adView withError:(NSError*)error { }
      - (void)adWasClicked:(ASAdView*)adView { }
      			
    • Swift
      //MARK: AerServ Banner Callbacks
      func adViewDidLoadAd(_ adView: ASAdView!) { }
      func adViewDidPreloadAd(_  adView: ASAdView!) { }
      func adViewDidFail(toLoadAd adView: ASAdView!, withError error: Error!) { }
      func adWasClicked(_ adView: ASAdView!) { }
      			

    Please refer to ASAdView.h for all available callbacks and descriptions of each. Settings for specifying the banner refresh time interval, preloading, and more can be found in the ASAdView header as well.

Step 4: Displaying Interstitial Ads

  • Step 4.1: Loading and Displaying Interstitials

    • Create an ASInterstitialViewController object with a placement setup on the AerServ + InMobi dashboard and a delegate that conforms to ASInterstitialViewControllerDelegate.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController() <ASInterstitialViewControllerDelegate>
        @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
        @end
        @implementation ViewController
        - (void)loadInterstitialAd {
          // Create the AerServ interstitial object
          self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
        }
        @end
        				
      • Swift
        import AerServSDK
        class ViewController: UIViewController, ASInterstitialViewControllerDelegate {
          var asInterstitialVC: ASInterstitialViewController?
          func loadInterstitialAd() {
            // Create the AerServ interstitial object
            asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
          }
        }
        				

    • Start the ad request by loading an ad with your specified settings.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController() <ASInterstitialViewControllerDelegate>
        @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
        @end
        @implementation ViewController
        - (void)loadInterstitialAd {
          // Create the AerServ interstitial object
          self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
          // Use loadAd to make a request to the AerServ ad server for an ad
          [self.asInterstitialVC loadAd];
        }
        @end
        				
      • Swift
        class ViewController: UIViewController, ASInterstitialViewControllerDelegate {
          var interstitial: ASInterstitialViewController?
          func loadInterstitialAd() {
            // Create the AerServ interstitial object
            asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
            // Use loadAd to make a request to the AerServ ad server for an ad
            asInterstitialVC?.loadAd()
          }
        }
        				
    • When the ad is ready, a callback event will be triggered. From the callback, the interstitial ad can be shown from a parent view controller.
      • Objective-C
        #import <InMobiSDK/InMobiSDK.h>
        @interface ViewController() <ASInterstitialViewControllerDelegate>
        @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
        @end
        @implementation ViewController
        - (void)loadInterstitialAd {
          // Create the AerServ interstitial object
          self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
          // Use loadAd to make a request to the AerServ ad server for an ad
          [self.asInterstitialVC loadAd];
        }
        #pragma mark - AerServ Interstitial Callbacks
        - (void)interstitialViewControllerAdLoadedSuccessfully:(ASInterstitialViewController*)viewController {
          [viewController showFromViewController:self];
        }
        @end
        				
      • Swift
        class ViewController: UIViewController, ASInterstitialViewControllerDelegate {
          var asInterstitialVC: ASInterstitialViewController?
          func loadInterstitialAd() {
            // Create the AerServ interstitial object
            asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
            // Use loadAd to make a request to the AerServ ad server for an ad
            asInterstitialVC?.loadAd()
          }
          //MARK: AerServ Interstitial Callbacks
          func interstitialViewControllerAdLoadedSuccessfully(_ viewController: ASInterstitialViewController!) {
            asInterstitialVC?.show(from: self)
          } 
        }
        				

  • Step 4.2: Optional Interstitial Steps

    Preloading Interstitial Ads

    Preloading an ad works in a similar fashion. Before loading the ad, the isPreload flag should be set to YES. Another callback event can be listened to for notification that a preloaded ad is ready to be shown.

    • Objective-C
      #import <InMobiSDK/InMobiSDK.h>
      @interface ViewController() <ASInterstitialViewControllerDelegate>
      @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
      @property(nonatomic) BOOL didPreload;
      @end
      @implementation ViewController
      /**
       * We check if the preload flag has been previously set. This is so that we don't waste an ad that has already been preloaded
       * and calling another load won't necessary fill.
       */
      - (void)loadAd {
        if(!self.didPreload) {
          self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
          self.asInterstitialVC.isPreload = YES;
          [self.asInterstitialVC loadAd];
        } else {
          NSLog(@"--- Ad is already loaded ---");
        }
      }
      - (void)showAd {
        if(self.didPreload) {
          [self.asInterstitialVC showFromViewController:aViewController];
        } else {
          NSLog(@"--- Interstitial hasn't preloaded ---");
        }
      }
      #pragma mark - AerServ Interstitial Callbacks
      - (void)interstitialViewControllerDidPreloadAd:(ASInterstitialViewController*)viewController {
        NSLog(@"--- Interstitial View Controller Did Preload Ad ---");
        self.didPreload = YES;
        // - [self.asInterstitialVC showFromViewController] can be called anything after this point.
      }
      - (void)interstitialViewControllerAdFailedToLoad:(ASInterstitialViewController*)viewController withError:(NSError*)error {
        NSLog(@"--- Interstitial ad failed: ', error, ' ---");
        self.didPreload = NO;
      }
      - (void)interstitialViewControllerDidDisappear:(ASInterstitialViewController*)viewController {
        NSLog(@"--- Interstitial ad did disappear ---");
        self.didPreload = NO;
      }
      @end
      			
    • Swift
      class ViewController: UIViewController, ASInterstitialViewControllerDelegate {
        var asInterstitialVC: ASInterstitialViewController?
        var didPreload = false
        /**
         * We check if the preload flag has been previously set. This is so that we don't waste an ad that has already been preloaded
         * and calling another load won't necessary fill.
         */
        func loadAd() {
          if(!didPreload) {
            asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
            asInterstitialVC?.isPreload = true
            asInterstitialVC?.loadAd()
          }
        }
        func showAd() {
          if(didPreload) {
            asInterstitialVC?.show(from: aViewController)
          } else {
            print("--- Interstitial hasn't preloaded ---")
          }
        }
        //MARK: AerServ Interstitial Callbacks
        func interstitialViewControllerDidPreloadAd(_ viewController: ASInterstitialViewController!) {
          print("---- Interstitial ViewController Did Preload Ad ---")
          didPreload = true
          // interstitial?.show(from: self) can be called anything after this point.
        }
        func interstitialViewControllerAdFailed(toLoad viewController: ASInterstitialViewController!, withError error: Error!) {
          print("--- Interstitial ad failed: ", error, " ---")
          didPreload = false;
        }
        func interstitialViewControllerDidDisappear(_ viewController: ASInterstitialViewController!) {
          print("--- Interstitial ad did disappear ---")
          didPreload = false;
        }
      }
      			
    Additional Interstitial Callbacks

    Other callback events that can be listened to are:

    • Objective-C
      #pragma mark - AerServ Interstitial Callbacks
      - (void)interstitialViewControllerWillAppear:(ASInterstitialViewController*)viewController { }
      - (void)interstitialViewControllerDidAppear:(ASInterstitialViewController*)viewController { }
      - (void)interstitialViewControllerWillDisappear:(ASInterstitialViewController*)viewController { }
      - (void)interstitialViewControllerDidDisappear:(ASInterstitialViewController*)viewController { }
      - (void)interstitialViewControllerAdWasTouched:(ASInterstitialViewController*)viewController { }
      - (void)interstitialViewControllerAdFailedToLoad:(ASInterstitialViewController*)viewController withError:(NSError*)error { }
      			
    • Swift
      //MARK: AerServ Interstitial Callbacks
      func interstitialViewControllerWillAppear(_ viewController: ASInterstitialViewController!) { }
      func interstitialViewControllerDidAppear(_ viewController: ASInterstitialViewController!) { }
      func interstitialViewControllerWillDisappear(_ viewController: ASInterstitialViewController!) { }
      func interstitialViewControllerDidDisappear(_ viewController: ASInterstitialViewController!) { }
      func interstitialViewControllerAdWasTouched(_ viewController: ASInterstitialViewController!) { }
      func interstitialViewControllerAdFailed(toLoad viewController: ASInterstitialViewController!, withError error: Error!) { }
      			

    Please refer to ASInterstitialViewController.h for all available callbacks and descriptions for each. Settings for supplying video player controls, and more can be found in the ASInterstitialViewController header as well.

Step 5: Additional Settings

Virtual Currency

  • Once you have setup your placement with virtual currency, there are two additional callbacks that conform to the protocol ASInterstitialViewControllerDelegate. The first callback will notify that the virtual currency data has loaded.

    • Objective-C
      #import <InMobiSDK/InMobiSDK.h>
      @interface ViewController() <ASInterstitialViewControllerDelegate>
      @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
      @end
      @implementation ViewController
      - (void)loadInterstitialAd {
        self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
        [self.asInterstitialVC loadAd];
      }
      #pragma mark - AerServ Interstitial Callbacks
      - (void)interstitialViewControllerAdLoadedSuccessfully:(ASInterstitialViewController*)viewController {
        [viewController showFromViewController:self];
      }
      /**
       * The first callback will notify when we load the creative. Note that you can also get the buyerName and buyer price throught the didLoadAdWithTransactionInfo and
       * didShowAdWithTransactionInfo.
       */
      - (void)interstitialViewControllerDidVirtualCurrencyLoad:(ASInterstitialViewController*)viewController vcData:(NSDictionary*)vcData {
        NSString* name = vcData[@"name"];
        NSNumber* rewardAmount = vcData[@"rewardAmount"];
        NSString* buyerName = vcData[@"buyerName"];
        NSNumber* buyerPrice = vcData[@"buyerPrice"];
        // Add your logic here  
      }
      /** 
       * The second callback will notify when the virtual currency has been rewarded. This will only fire after the user has watch 100% of the video on a virtual currency
       * enable placement.
       */
      - (void)interstitialViewControllerDidVirtualCurrencyReward:(ASInterstitialViewController*)viewController vcData:(NSDictionary*)vcData {
        NSString* name = vcData[@"name"];
        NSNumber* rewardAmount = vcData[@"rewardAmount"];
        // Add your logic here  
      }
      @end
      		
    • Swift
      class ViewController: UIViewController, ASInterstitialViewControllerDelegate {
        var asInterstitialVC: ASInterstitialViewController?
        func loadInterstitialAd() {
          asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
          asInterstitialVC?.loadAd()
        }
        //MARK: AerServ Interstitial Callback
        func interstitialViewControllerAdLoadedSuccessfully(_ viewController: ASInterstitialViewController!) {
          asInterstitialVC?.show(from: self)
        }
        /**
         * The first callback will notify when we load the creative. 
         */
        func interstitialViewControllerDidVirtualCurrencyLoad(_ viewController: ASInterstitialViewController!, vcData: [AnyHashable : Any]!) {
          let name: String = vcData?["name"] as! String
          let amount: NSNumber = vcData?["rewardAmount"] as! NSNumber
          let buyerName: String = vcData?["buyerName"] as! String
          let buyerPrice: NSNumber = vcData?["buyerName"] as! NSNumber
          // Add your logic here  
        }
        /**
         * The second callback will notify when the virtual currency has been rewarded. This will only fire after the user has watch 100% of the video on a virtual currency 
         * enable placement.
         */
        func interstitialViewControllerDidVirtualCurrencyReward(_ viewController: ASInterstitialViewController!, vcData: [AnyHashable : Any]!) {
          let name: String = vcData?["name"] as! String
          let amount: NSNumber = vcData?["rewardAmount"] as! NSNumber
          // Add your logic here  
        }
      }
      		

    For both of these callbacks, there is a vcData dictionary object attached that will contain the keys "name" and "rewardAmount".

  • Ad Transaction Information

    During the process of showing an ad, the InMobi SDK will additionally return information pertaining to the buyer for your ad space and the price that the ad space was bought for. This detailed information can be found from these callbacks:

    • Objective-C
      #import <InMobiSDK/InMobiSDK.h>
      @interface ViewController() <ASInterstitialViewControllerDelegate, ASAdViewDelegate>
      @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
      @property(nonatomic, strong) ASAdView* asAdView;
      @end
      @implementation ViewController 
      /**
       * When gettings the ad transaction information, no change are needed in how we load the ASInterstitialViewController. We
       * just need to add in the callback.
       */
      - (void)loadInterstitialAd {
        self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
        [self.asInterstitialVC loadAd];
      }
      /**
       * When gettings the ad transaction information, no change are needed in how we load the ASAdView. We
       * just need to add in the callback.
       */
      - (void)loadBannerAd {
        self.asAdView = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];
        self.asAdView.delegate = self;
        [self.view addSubview:self.asAdView];
        [self.asAdView loadAd];
      }
      #pragma mark - AerServ Interstitial Callbacks
      - (void)interstitialViewControllerAdLoadedSuccessfully:(ASInterstitialViewController*)viewController {
        [viewController showFromViewController:self];
      }
      /**
       * The didLoadAdWithTransactionInfo callback will contain the transaction information of the ad from the first load attempt. The transaction 
       * information from this callback may be different from the ad the produce the impression.
       */
      - (void)interstitialAdManager:(ASInterstitialAdManager*)viewController didLoadAdWithTransactionInfo:(NSDictionary*)transactionInfo {
        NSString* buyerName = transcationData[@"buyerName"];
        NSNumber* buyerPrice = transcationData[@"buyerPrice"];
        // Add your logic here  
      }
      /**
       * The didShowAdWithTransactionInfo callback will cotanin the transaction information of the ad that produced an impression.  
       */
      - (void)interstitialViewController:(ASInterstitialViewController*)viewController didShowAdWithTransactionInfo:(NSDictionary*)transcationData {
        NSString* buyerName = transcationData[@"buyerName"];
        NSNumber* buyerPrice = transcationData[@"buyerPrice"];
        // Add your logic here  
      }
      #pragma mark - AerServ Banner Callbacks
      - (UIViewController*)viewControllerForPresentingModalView {
        return self;
      }
      /**
       * The didLoadAdWithTransactionInfo callback will contain the transaction information of the ad from the first load attempt. The transaction 
       * information from this callback may be different from the ad the produce the impression.
       */
      - (void)adView:(ASAdView*)adVidew didLoadAdWithTransactionInfo:(NSDictionary*)transcationData {
        NSString* buyerName = transcationData[@"buyerName"];
        NSNumber* buyerPrice = transcationData[@"buyerPrice"];
        // Add your logic here  
      }
      /**
       * The didShowAdWithTransactionInfo callback will cotanin the transaction information of the ad that produced an impression.  
       */
      - (void)adView:(ASAdView*)adVidew didShowAdWithTransactionInfo:(NSDictionary*)transcationData {
        NSString* buyerName = transcationData[@"buyerName"];
        NSNumber* buyerPrice = transcationData[@"buyerPrice"];
        // Add your logic here
      }
      @end
      		
    • Swift
      class ViewController: UIViewController, ASInterstitialViewControllerDelegate, ASAdViewDelegate {
        var asInterstitialVC: ASInterstitialViewController?
        var asAdView: ASAdView?
        /**
         * When gettings the ad transaction information, no change are needed in how we load the ASInterstitialViewController. We
         * just need to add in the callback.
         */
        func loadInterstitialAd() {
          asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
          asInterstitialVC?.loadAd()
        }
        /**
         * When gettings the ad transaction information, no change are needed in how we load the ASAdView. We
         * just need to add in the callback.
         */
        func loadBannerAd() {
          asAdView? = ASAdView(placementID: "1024876" andAdSize: ASBannerSize)
          asAdView?.delegate = self
          view.addSubview(asAdView!)
          asAdView?.loadAd()
        }
        //MARK: AerServ Interstitial Callbacks
        func interstitialViewControllerAdLoadedSuccessfully(_ viewController: ASInterstitialViewController!) {
          asInterstitialVC?.show(from: self)
        }
        /**
         * The didLoadAdWithTransactionInfo callback will contain the transaction information of the ad from the first load attempt. The transaction 
         * information from this callback may be different from the ad the produce the impression.
         */
        func interstitialViewController(_ viewController: ASInterstitialViewController!, didLoadAdWithTransactionInfo transcationData: [AnyHashable : Any]!) {
          let buyerName:String = transcationData?["buyerName"] as! String;
          let buyerPrice:NSNumber = transcationData?["buyerName"] as! NSNumber;
          // Add your logic here
        }
        /**
         * The didShowAdWithTransactionInfo callback will cotanin the transaction information of the ad that produced an impression.  
         */
        func interstitialViewController(_ viewController: ASInterstitialViewController!, didShowAdWithTransactionInfo transcationData: [AnyHashable : Any]!) {
          let buyerName:String = transcationData?["buyerName"] as! String;
          let buyerPrice:NSNumber = transcationData?["buyerName"] as! NSNumber;
          // Add your logic here
        }
        //MARK: Aerserv Banner Callback
        func viewControllerForPresentingModalView() -> UIViewController! {
          return self  
        }
        /**
         * The didLoadAdWithTransactionInfo callback will contain the transaction information of the ad from the first load attempt. The transaction 
         * information from this callback may be different from the ad the produce the impression.
         */ 
        func adView(_ adView: ASAdView!, didLoadAdWithTransactionInfo transcationData: [AnyHashable : Any]!) { 
          let buyerName:String = transcationData?["buyerName"] as! String;
          let buyerPrice:NSNumber = transcationData?["buyerName"] as! NSNumber;
          // Add your logic here
        }
        /**
         * The didShowAdWithTransactionInfo callback will cotanin the transaction information of the ad that produced an impression.  
         */
        func adView(_ adView: ASAdView!, didShowAdWithTransactionInfo transcationData: [AnyHashable : Any]!) { 
          let buyerName:String = transcationData?["buyerName"] as! String;
          let buyerPrice:NSNumber = transcationData?["buyerName"] as! NSNumber;
          // Add your logic here
        }
      }
      		

    The transactionData dictionary object contains keys for "buyerName" and "buyerPrice" that can be accessed for the transaction information values.

    Adding Publisher Keys

    Custom revenue reports can be generated via the SDK by assigning a dictionary object with publisher key value pairs to the pubKeys property. This is available for both interstitials and banners. For details about publisher keys, click here.

    • Objective-C
      #import <InMobiSDK/InMobiSDK.h>
      @interface ViewController() <ASInterstitialViewControllerDelegate, ASAdViewDelegate>
      @property(nonatomic, strong) ASInterstitialViewController* asInterstitialVC;
      @property(nonatomic, strong) ASAdView* asAdView;
      @end
      @implementation ViewController
      /**
       * Before loading an ad with ASInterstitialViewController, you'll need to set the values for pubKeys.
       */
      - (void)loadInterstitialAd {
        self.asInterstitialVC = [ASInterstitialViewController viewControllerForPlacementID:@"1000741" withDelegate:self];
        self.asInterstitialVC.pubKeys = @{@"channel_category":@"music", @"content_rating":@"4 stars"}; // Dictionary containing publisher keys
        [self.asInterstitialVC loadAd];
      }
      /**
       * Before loading an ad with ASAdView, you'll need to set the values for pubKeys.
       */
      - (void)loadBannerAd() {
        self.asAdView = [ASAdView viewWithPlacementID:@"1024876" andAdSize:ASBannerSize];
        self.asAdView.delegate = self;
        self.asAdView.pubKeys = @{@"partner_name":@"bloomberg", @"episode_id":@"77889"}; // Dictionary containing publisher keys
        [self.view addSubview:self.asAdView];
        [self.asAdView loadAd];
      }
      #pragma mark - AerServ Interstitial Callbacks
      - (void)interstitialViewControllerAdLoadedSuccessfully:(ASInterstitialViewController*)viewController {
        [viewController showFromViewController:self];
      }
      #pragma mark - AerServ Banner Callbacks
      - (UIViewController*)viewControllerForPresentingModalView {
        return self;
      }
      @end
      		
    • Swift
      class ViewController: UIViewController, ASInterstitialViewControllerDelegate, ASAdViewDelegate {
        var asInterstitialVC: ASInterstitialViewController?
        var asAdView: ASAdView?
        /**
         * Before loading an ad with ASInterstitialViewController, you'll need to set the values for pubKeys.
         */
        func loadInterstitialAd() {
          asInterstitialVC? = ASInterstitialViewController(forPlacementID: "1000741", with: self)
          asInterstitialVC?.pubKeys = ["channel_category": "music", "content_rating": "4 stars"] // Dictionary containing publisher keys
          asInterstitialVC?.loadAd()
        }
        /**
         * Before loading an ad with ASAdView, you'll need to set the values for pubKeys.
         */
        func loadBannerAd() {
          asAdView? = ASAdView(placementID: "1024876" andAdSize: ASBannerSize)
          asAdView?.delegate = self
          asAdView?.pubKeys = ["partner_name": "bloomberg", "episode_id": "77889"] // Dictionary containing publisher keys.
          view.addSubview(asAdView!)
          asAdView?.loadAd()
        }
        //MARK: AerServ Interstitial Callbacks
        func interstitialViewControllerAdLoadedSuccessfully(_ viewController: ASInterstitialViewController!) {
          asInterstitialVC?.show(from: self)
        }
        //MARK: AerServ Banner Callbacks
        func viewControllerForPresentingModalView() -> UIViewController! {
          return self  
        }
      }
      		

    Note: Publisher Keys can also be used as custom macro on the SSUI. Please contact support on instructions on how to use this feature.

  • Enabling Geolocation Targeting

    If your application already requests permission for geolocation, skip this step. Enabling geolocation will help target ads relevant to your user's physical location. This can be done by adding key-value pairs to your application's Info.plist. The keys will be:

    • NSLocationAlwaysUsageDescription
    • NSLocationWhenInUseUsageDescription

    The value for both will be a string that will be displayed when your application is requesting for geolocation permission.

    <key>NSLocationAlwaysUsageDescription</key> 
    <string>Location is used to help target content to your general area</string>
    <key>NSLocationWhenInUseUsageDescription</key> 
    <string>Location is used to help target content to your general area</string>
    	
  • Disabling App Transport Security for iOS 9 and above

    Select your application's Info.plist, right-click on it and open as source code. Copy the following code into your Info.plist's xml.

    <key>NSAppTransportSecurity</key>
    <dict>
      <key>NSAllowsArbitraryLoads</key><true/>
    </dict>
    	
  • iOS 12 Wifi Settings

    Enable XCode WiFi Settings

    From iOS 12 onwards Apple has introduced privacy settings to access WiFi details. If the publisher decides to share wifi details, they can take advantage of targeted ads. Benefits of ad targeting are that the ads are more useful and meaningful to users.

    How to enable Access Wifi Information?

    1. Enable access WiFi information feature to your App ID.


    2. Enable access WiFi information feature for your target app from XCode capabilities.


    3. WiFi Access should get added to your App.entitlements file. If not please add the following code to your App.entitlements file.
              <dict>
                  <key>com.apple.developer.networking.wifi-info</key>
                  <true/>
              </dict>
      		

    AVAudioSession event changes in WKWebView

    WKWebView ignores AVAudioSessionCategory, Publisher can handle audio interruptions by registering to observe AVAudioSessionInterruptionnotification posted by AVAudioSession. Publisher should ensure minimum possible disruption, and the most graceful possible recovery, from the perspective of the user.

    Observing Audio Interruptions

    To handle audio interruptions, begin by registering to observe notifications of type AVAudioSessionInterruptionNotification.

        - (void)registerForAudioInterruptionNotification {
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleAudioSessionInterruption:) name:AVAudioSessionInterruptionNotification object:audioSession];
    }
    - (void)handleAudioSessionInterruption:(NSNotification *)notification {
        NSNumber *interruptionType = [[notification userInfo] objectForKey:AVAudioSessionInterruptionTypeKey];
        NSNumber *interruptionOption = [[notification userInfo] objectForKey:AVAudioSessionInterruptionOptionKey];
        switch (interruptionType.unsignedIntegerValue) {
            case AVAudioSessionInterruptionTypeBegan: {
                /* the system has interrupted your audio session */
                /* Pause, Save State, Update UI */
                break;
            }
            case AVAudioSessionInterruptionTypeEnded: {
                if (interruptionOption && interruptionOption.unsignedIntegerValue == AVAudioSessionInterruptionOptionShouldResume) {
                    /* the interruption has ended */
                    /* Resume, Update State, Update UI */
                }
                break;
            }
        }
    }
    	

    The posted NSNotification instance contains a userInfo dictionary providing the details of the interruption. You can determine the type of interruption by retrieving the AVAudioSessionInterruptionType value from the userInfo dictionary. The interruption type indicates whether the interruption has begun or has ended. If the interruption type is AVAudioSessionInterruptionTypeEnded, the userInfo dictionary might contain an AVAudioSessionInterruptionOptions value.

    An options value of AVAudioSessionInterruptionOptionShouldResume is a hint that indicates whether your app should automatically resume playback if it had been playing when it was interrupted. Media playback apps should always look for this flag before beginning playback after an interruption. If it’s not present, playback should not begin again until initiated by the user. Apps that don’t present a playback interface, such as a game, can ignore this flag and reactivate and resume playback when the interruption ends.

    Please Note: There is no guarantee that a begin interruption will have a corresponding end interruption. Your app needs to be aware of a switch to a foreground running state or the user pressing a Play button. In either case, determine whether your app should reactivate its audio session.

    For more details, please refer to the following:

    1. https://developer.apple.com/documentation/avfoundation/avaudiosession/1616596-interruptionnotification
    2. https://developer.apple.com/library/archive/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/HandlingAudioInterruptions/HandlingAudioInterruptions.html
  • Version History

    SDK 9.0

    • 9.0.2: 11/20/19

      - Update IMAB MoPub Plugin to support MoPub v5.10.0

      - Add SDK support for Xcode 10.2

    • 9.0.1: 10/25/19

      - Upgrade OMSDK to v1.2.19

      - Separate Moat SDK from Inmobi Core SDK

      - Separate OMSDK from Inmobi Core SDK

      - Add CocoaPods for DFP AB plugin

      - Add CocoaPods for MoPub AB plugin

      - GDPR changes, addition of new key "gdpr_consent"

    • 9.0.0: 9/20/19

      - Changes to support iOS 13

      - New and improved Modularised SDK design

      - Add InMobiMediationSDK.framework to your project for AerServ Mediation.

      - Addressing issue with layering of FAN banners upon refresh

      - SKStoreProductViewController crash fix.

      - Removed Support for iOS 8.

      - Removed Support for AerServ Native ad format.

      - Removed UIWebView from InMobi SDK. Viewability Partners might be using it.

      - Size reduction for both Framework and ipa inflation.

      - Various Bug Fixes and performance improvements

      - Adapter updates for the following mediation partners:

      • MoPub - v5.9.0
      • Google Mobile Ads - v7.50.0

      - APIs Added

      • IMBanner Class + -(void)cancel;
      • IMInterstitial Class + -(void)cancel;
      - APIs Added
      • ASAdView Class
        - @property (nonatomic, assign) ASEnvironmentType env;
        - @property (nonatomic, assign) ASPlatformType platform;
        - @property (nonatomic, assign) BOOL isMuted;
        - @property (nonatomic, assign) BOOL outlineAd;
        - @property (nonatomic, assign) BOOL sizeAdToFit;
        - @property (nonatomic, assign) BOOL useHeaderBidding;
        - @property (nonatomic, strong) NSArray* keyWords;
        - @property (nonatomic, assign) BOOL allowAdvertiserCloseButton;
        - -(void)forceRefreshAd;
        - -(CGSize)adContentSize;
        - -(void)rotateToOrientation:(UIInterfaceOrientation)newOrientation;
        - -(void)play;
        - -(void)pause;

      • ASAdViewDelegate Protocol
        - -(void)willLeaveApplicatonFromAd:(ASAdView*)adView;
        - -(void)adSizeChanged:(ASAdView*)adView;
        - -(void)adView:(ASAdView*)adView didFireAdvertiserEventWithMessage:(NSString*)msg;

      • ASInterstitialViewController Class
        - @property (nonatomic, assign) ASEnvironmentType env;
        - @property (nonatomic, assign) ASPlatformType platform;
        - @property (nonatomic, assign) BOOL isMuted;
        - @property (nonatomic, assign) BOOL showOutline;
        - @property (nonatomic, assign) BOOL useHeaderBidding;
        - -(void)play;
        - -(void)pause;
      • ASInterstitialViewControllerDelegate Protocol
        - -(void)interstitialViewControllerAdInteraction:(ASInterstitialViewController*)viewController;
        - -(void)interstitialViewController:(ASInterstitialViewController*)viewController didFireAdvertiserEventWithMessage:(NSString*)msg;
    • 8.2.0: 8/5/19
      • Chrome Custom tabs support
      • Thread Optimizations
      • Bug Fixes for SDK and AudienceBidder Plugin
    • 8.1.2: 7/18/19
      • Size reduction
      • Support for Audience Bidding for DFP
      • New api to set slot size for Banner in Audience Bidding
    • 8.1.1: 6/19/19
      • Updated AdColony SDK support to 3.3.10
      • Updated Audience Network (Facebook) support to 5.3.1
    • 8.1.0: 5/14/19
      • DFP Plugin Support
      • Mopub Audience Bidding Plugin Keyword Handling
      • Bug fixes
    • 8.0.8: 4/17/19
      • Bug Fixes
    • 8.0.7: 4/05/19
      • Additional support for higher granularity keywords
    • 8.0.5: 3/11/19
      • Audience Bidder for the Mopub Plugin
      • Telaria Adapter Deprecation
      • Flurry Banner Adapter Deprecation
      • Applovin 3rd Party API Reporting updates
      • Chartboost 3rd Party API Reporting updates
      • Mediated SDK updates
      • Bug Fixes
    • 8.0.2: 12/13/18
      • Mediation bug Fixes
    • 8.0.1: 11/28/18
      • Unified InMobi + AerServ SDK