iAd Framework updates for iOS 4.2

A quick look at the changes made to the iAd framework in iOS 4.2 to accommodate the larger iPad screen size.

Ad Banner View Content Size

The release of iOS 4.2 means that we finally have a unified OS running across iPad, iPhone and iPod Touch devices. This means that iOS features such as multi-tasking and folders finally come to the iPad. It also means that iAd is now available to applications running on the iPad.

From a developer perspective the only significant change to the iAd framework in iOS 4.2 is to allow for the increased screen space of the iPad. The iAd Banner view dimensions for the iPhone and iPad are as follows:

  • iPhone: 320 x 50 points (portrait), 480 x 32 points (landscape)
  • iPad: 766 x 66 points (portrait), 1024 x 66 points (landscape)

For an example on how to create the iAd Banner View you can refer back to the original TabNav example app (updated here and here). The basic code to create a banner view prior to iOS 4.2 is as follows:

- (void)createBannerView {

  Class cls = NSClassFromString(@"ADBannerView");
  if (cls) {
    ADBannerView *adView = [[cls alloc] initWithFrame:CGRectZero];
    adView.requiredContentSizeIdentifiers = [NSSet setWithObjects:
                               ADBannerContentSizeIdentifier320x50,
                               ADBannerContentSizeIdentifier480x32,
                               nil];

    // Set the current size based on device orientation
    adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
    adView.delegate = self;
    
    adView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin |
                              UIViewAutoresizingFlexibleRightMargin;
  
    // Set intital frame to be offscreen
    CGRect bannerFrame =adView.frame;
    bannerFrame.origin.y = self.view.frame.size.height;
    adView.frame = bannerFrame;
    
    self.bannerView = adView;
    [self.view addSubview:adView];
    [adView release];
  }
}

When creating the banner view you need to specify the required sizes. Since the sizes will be different between the iPhone and the iPad the previous identifiers ADBannerContentSizeIdentifier320x50 and AdBannerContentSIzeIdentifier480x32 are now deprecated. If you compile against the iOS 4.2 SDK you will see the following runtime warning messages in Xcode:

ADBannerView: ADBannerContentSizeIdentifier480x32 is deprecated, please use
ADBannerContentSizeIdentifierLandscape instead
ADBannerView: ADBannerContentSizeIdentifier320x50 is deprecated, please use
ADBannerContentSizeIdentifierPortrait instead

If you only intend to support iOS 4.2 the solution is, as suggested in the deprecation message, to use the ADBannerContentSizeIdentifierPortrait and ADBannerContentSizeIdentifierLandscape symbols instead. This will ensure that the correct banner view size is used for both the iPad and the iPhone.

In the example we are also targeting older versions of iOS all the way back to 3.1 (of course iAds will not be displayed on iOS 3.1 but we do not want the App to crash). Since these new symbols are not available on iOS versions 4.1 and older we need to do some additional runtime checks. The modified createBannerView method therefore becomes as follows:

- (void)createBannerView {

  Class cls = NSClassFromString(@"ADBannerView");
  if (cls) {
    
    if (&ADBannerContentSizeIdentifierPortrait != nil) {
      kTabnavADBannerContentSizeIdentifierPortrait = ADBannerContentSizeIdentifierPortrait;
    } else {
      kTabnavADBannerContentSizeIdentifierPortrait = ADBannerContentSizeIdentifier320x50;
    }
    
    if (&ADBannerContentSizeIdentifierLandscape != nil) {
      kTabnavADBannerContentSizeIdentifierLandscape = ADBannerContentSizeIdentifierLandscape;
    } else {
      kTabnavADBannerContentSizeIdentifierLandscape = ADBannerContentSizeIdentifier480x32;
    }
    
    ADBannerView *adView = [[cls alloc] initWithFrame:CGRectZero];
    adView.requiredContentSizeIdentifiers = [NSSet setWithObjects:
                             kTabnavADBannerContentSizeIdentifierPortrait,
                             kTabnavADBannerContentSizeIdentifierLandscape,
                             nil];

    // Set the current size based on device orientation
    adView.currentContentSizeIdentifier = kTabnavADBannerContentSizeIdentifierPortrait;
    adView.delegate = self;

    adView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin |
                              UIViewAutoresizingFlexibleRightMargin;

    // Set intital frame to be offscreen
    CGRect bannerFrame =adView.frame;
    bannerFrame.origin.y = self.view.frame.size.height;
    adView.frame = bannerFrame;
    
    self.bannerView = adView;
    [self.view addSubview:adView];
    [adView release];
  }
}

The trick here is to test if the ADBannerContentSizeIndentifierPortrait and ADBannerContentSizeIndentifierLandscape symbols exist and if they do not fallback to the old symbols. The correct symbols are used to set two additional NSString references defined in the view controller class implementation:

NSString *kTabnavADBannerContentSizeIdentifierPortrait;
NSString *kTabnavADBannerContentSizeIdentifierLandscape;

Once these two NSString references are set in createBannerView they are then used in place of the iAd framework defined values. The only other place that the banner view size needs to be set is when responding to orientation changes:

- (void)changeBannerOrientation:(UIInterfaceOrientation)toOrientation {
  if (UIInterfaceOrientationIsLandscape(toOrientation)) {
    self.bannerView.currentContentSizeIdentifier = kTabnavADBannerContentSizeIdentifierLandscape;
  } else {
    self.bannerView.currentContentSizeIdentifier = kTabnavADBannerContentSizeIdentifierPortrait;
  }
}