Supplementing iAd Placement with AdMob

Supplementing iAd Placement with AdMob

Tutorial Details
  • Technology: iOS SDK
  • Difficulty: Intermediate
  • Completion Time: 30 Minutes

Click-based advertising within a mobile application is a great way to make some money off of your free or inexpensive applications. While there are many choices out there, many iOS developers tend to go with the iAds platform for a variety of reasons including simplicity, aesthetics, and a high CPM.

Although iAds is great, it’s not quite the silver bullet you might be looking for. Being that iAds serves up very specific content from providers that must have a very specific contract with Apple, they often fail to fulfill in certain situations. These situations might be in a geolocation that ads have not been placed in, foreign countries, or just lack of publishers for a given time period.

In the production version of the Caterpillar Application I created, I implemented iAds and noticed that the fill rate falls somewhere in the 75% range. That’s not bad, however AdMob is usually somewhere in the 98% range! This brings me to the purpose of this post.

Wouldn’t it be great to have a hybrid solution to fill the ad spots with AdMob ads when iAds fails to deliver?


Step 1: iAds Setup

Since this is not an iAds tutorial, we are just going to start with a very simple iAds setup. It will be a banner view at the top of a regular UIView. I have begun with a single view project template and added the following code to the ViewController.h file:

#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
@interface ViewController : UIViewController<ADBannerViewDelegate>
@property (nonatomic, strong) ADBannerView *bannerView;
@end

This is just declaring our banner ad that will be displayed in the view. Now, let’s take a look at the code to display the ad banner inside of ViewController.m:

#import "ViewController.h"
@implementation ViewController
@synthesize bannerView = _bannerView;
- (void)viewDidLoad
{
    [super viewDidLoad];
    self.bannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)];
    [self.bannerView setRequiredContentSizeIdentifiers:[NSSet setWithObjects:
                                                        ADBannerContentSizeIdentifierPortrait, nil]];
    self.bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    [self.bannerView setDelegate:self];
    [self.view addSubview:self.bannerView];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
    NSLog(@"iad failed");
}
@end

This loads up an ADBannerView at the top of the window set in portrait mode. As of right now, when iAds fail to load, it will simply print “iAd Failed” to the log as you can see in the bannerView:didFailToReceiveAdWithError delegate method. We will make use of this delegate method in order to replace the iAd banner with an AdMob banner.


Step 2: AdMob Configuration

Start by downloading the iOS AdMob SDK here:

http://code.google.com/mobile/ads/download.html

Extract it somewhere on disk and drag every file into your project. When asked if you want to copy the files in, check yes.

There are also some libraries that you must link in, in order to use AdMob:

  • AudioToolbox
  • MessageUI
  • SystemConfiguration
  • CoreGraphics

Once you have done this, you should be all set to implement the AdMob ads.


Step 3: Fill the iAd Spot With AdMob

Let’s start by revisiting ViewController.h and updating the code to look like this:

#import <UIKit/UIKit.h>
#import <iAd/iAd.h>
#import "GADBannerView.h"
@interface ViewController : UIViewController<ADBannerViewDelegate, GADBannerViewDelegate>
@property (nonatomic, strong) ADBannerView *bannerView;
@property (nonatomic, strong) GADBannerView *admobBannerView;
@end

All we did here was tell our class to be a delegate of GADBannerView and created a property for a GADBannerView. Also, make sure that you @synthesize the admobBannerView in the ViewController.m file.

The last part is to replace the iAd with the AdMob banner when it fails to load. This can be done by adding some code to the bannerView:didFailToReceivedAdWithError method in ViewController.m:

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
    // 1
    [self.bannerView removeFromSuperview];
    // 2
    _admobBannerView = [[GADBannerView alloc]
                    initWithFrame:CGRectMake(0.0,0.0,
                                             GAD_SIZE_320x50.width,
                                             GAD_SIZE_320x50.height)];
    // 3
    self.admobBannerView.adUnitID = @"a14ec3f0a2028f2";
    self.admobBannerView.rootViewController = self;
    self.admobBannerView.delegate = self;
    // 4
    [self.view addSubview:self.admobBannerView];
    [self.admobBannerView loadRequest:[GADRequest request]];
}

So, here’s what is going on:

  1. We remove the iAd banner from the current view. It will no longer be needed for the duration of this session. You could get tricky and try to make more requests to iAds, but it’s not really necessary.
  2. Here we instantiate the AdMob banner telling it to give us a banner that is 320 by 50 and place it at the top of the screen.
  3. This is the setup code for the AdMob banner (Feel free to use my ad unit id ;) ).
  4. Finally, we add the AdMob banner to our view and tell it to fetch an ad.

Step 4: Testing It Out

One thing to note is, you will never see iAds fail in the simulator. Perhaps if you had the Internet disabled you might, but then you wouldn’t even be able to fetch the AdMob ad. The best way to test is to simply force the call of the bannerView:didFailToReceiveAdWithError method from inside of viewDidLoad:

[self bannerView:self.bannerView didFailToReceiveAdWithError:nil];

This will simulate the iAd failing and run through the code to fetch and display the AdMob ads.


Step 5: Final Steps

Now that we have this dual solution in place, it is very unlikely that the user won’t see an ad. However, there is still that slight chance that both iAd and AdMob fail. In that case, I like to give the user a break and not show them anything. Sort of like a freebie for the day ;). So, the final method will be called when AdMob fails to load.

- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error {
    [self.admobBannerView removeFromSuperview];
}

As you might expect, when AdMob fails, we remove its view from the screen and the user wins!


Wrap Up

I hope that you have found this tutorial useful for bleeding every penny out of your users your development efforts. Although I have used AdMob, you are free to use this same design pattern to combine/chain any of the Ad networks that you prefer to work with. You may download the source code for this tutorial at the very top.

If you have any questions or comments, feel free to leave them here or write me on Twitter.

Happy coding!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • GG

    Hi Brandon,
    Great Tutorial !

    I know this might be not directly related to Tutorial but,
    I am from India and I want to use AdMob in my HTML5 App that I have created.

    But there are few concerns.
    I heard AdMob tends to deactivate User Account abruptly, and users are having problems retrieving the amount earned. Most of them concerned users seem to be from other than US.

    Should I be troubled?

  • http://supertecnoboff.co.uk Daniel

    Hi,

    Great tutorial. It was really useful. Just a few questions:

    1) Obviously if I was to implement this into one of my apps I would want to make money from the AdMob ads too. So am I right in saying that I have to replace “adUnitID” with my adUnitID??? And how do I find out my “adUnitID”? Will it be available on my Google Adsense account or do I need to make a Google AdMob account?

    2) Does this work properly on iOS 4 and higher? Yes or no?

    Thank you for your time,

    Dan

    • http://brandontreb.com Brandon Trebitowski
      Author

      @Daniel

      1. The adUnitID can be obtained from your Admob account. You have to set up your app and it will generate a unique id for you. Just replace mine and you should be good to go.

      2. Yep!

      @GG

      Admob has a 99% uptime. I would not be concerned. I have been using them for years without interrupted service.

  • Wayne

    Hi great tutorial,
    Couple of questions..1. before the iAd shows a white rectangle appears, how can we move that?
    and 2. how can i pass the add from 1 view controller to another in a tabbed view, i am using IB.

    thanks

  • mitch

    Amazing Tutorial… Very simple and is working perfectly..

    May I ask you if you time to do it even for mediation. Thanks very much..

  • M

    Great Tutorial! Just what I needed. Is there a quick way to place the ads at the bottom, rather than the top?

    • http://www.facebook.com/bmccaul1 Brian McCaul

      In the rect for the frame, the first two numbers are the x & y coordinates for the top left corner of the ad banner. You can simply change them as such to determine the height of the screen and subtract the size of the banner (in this case, 50). This should work for a portrait only implementation.

      self.bannerView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height - 50, 320, 50)];

      _admobBannerView = [[GADBannerView alloc]

      initWithFrame:CGRectMake(0.0,self.view.frame.size.height - 50,

      GAD_SIZE_320x50.width,

      GAD_SIZE_320x50.height)];

  • AdamP

    Im trying to implement this in my Xcode project. In the .m file I am getting an error message saying ‘Property ‘bannerView’ not found on object type “…ViewController” in the [self.bannerView removeFromSuperview];

    What am I doing wrong?