Advertisement

Supplementing iAd Placement with AdMob

by
Student iconAre you a student? Get a yearly Tuts+ subscription for $45 →

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!

Advertisement