Integrating iAd in a PhoneGap Project

Introduction:
As the name suggests iAd is a mobile advertising platform provided by Apple to embed advertisements into the app. The new feature of iAd makes the content of the app more lively and dynamic, since clicking on an advertisement unlike the previous one it does not navigate away to Safari but opens a new Pop-up Window for the Ad inside the app.

Description:
To integrate an Ad using the iAd framework we need to mainly modify the MainViewController.h and MainViewController.m files by adding some additional code to it.

Below is the integration guide as follows.

We need to open project navigator, then click on the Build Phases tab.

Here we will find the row Link Binary With Libraries. We need to add iAd.framework to the project by clicking on the Add(+) button( at lower left end).

Now, let’s open up MainViewController.h present in the “Class” folder of the app, and drop in the following code:

		#import <iAd/iAd.h>

		@interface MainViewController : CDVViewController<ADBannerViewDelegate>{		
			ADBannerView *adView;
		}
		@end

So, finally our MainViewController.h will look something like below:

#import <Cordova/CDVViewController.h>
#import <Cordova/CDVCommandDelegateImpl.h>
#import <Cordova/CDVCommandQueue.h>
#import <iAd/iAd.h>

@interface MainViewController : CDVViewController<ADBannerViewDelegate>{
ADBannerView *adView;
}
@end

@interface MainCommandDelegate : CDVCommandDelegateImpl
@end

@interface MainCommandQueue : CDVCommandQueue
@end

Also we need to modify MainViewController.m by adding the following code.

In viewDidload method, add:

     adView.delegate= self;

In viewDidUnload method, add:

     [adView release];

In webViewDidFinishLoad method, add:

		adView = [[ADBannerView alloc] initWithFrame:CGRectZero];

		if([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait || 
   			
		   [UIApplication sharedApplication].statusBarOrientation ==  
          		       UIInterfaceOrientationPortraitUpsideDown) {

  		        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
		}
		else {
  		     adView.currentContentSizeIdentifier =ADBannerContentSizeIdentifierLandscape;
		}

		adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
		
		CGRect adFrame = adView.frame;

		adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
	
		adView.frame = adFrame;
		
		[self.view addSubview:adView];

Till now, we have added the view to the MainViewController.m file to display the Ad while in the next modification, we need to handle the orientation changes from portrait to landscape mode, and vice-versa.
iAd advertisements have different sizes, which are better suited to a given orientation. But, this has not handled automatically.

If we don’t have a willAnimateRotationToInterfaceOrientation method, we need to add it, and drop in the following code:

		
(void)willAnimateRotationToInterfaceOrientation:
		  (UIInterfaceOrientation)newInterfaceOrientation duration:
		  (NSTimeInterval)duration {
  		  	BOOL hide = (newInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
			          newInterfaceOrientation == UIInterfaceOrientationLandscapeRight);
  
		  	[[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:
								UIStatusBarAnimationNone];
  
		 	 CGRect mainFrame = [[UIScreen mainScreen] applicationFrame];
  		
		  	[self.view setFrame:mainFrame];


			if (newInterfaceOrientation != UIInterfaceOrientationLandscapeLeft &&
		     	    newInterfaceOrientation != UIInterfaceOrientationLandscapeRight) {
    				adView.currentContentSizeIdentifier =
				ADBannerContentSizeIdentifierPortrait;
    				[self.view bringSubviewToFront:adView];
    				adView.frame = CGRectMake(0.0, self.view.frame.size.height-				             			adView.frame.size.height,
				adView.frame.size.width,adView.frame.size.height);

  			}
  			else {
   				adView.currentContentSizeIdentifier =
				 ADBannerContentSizeIdentifierLandscape;
   
				[self.view bringSubviewToFront:adView];
   
				adView.frame = CGRectMake(0.0, self.view.frame.size.width -
							adView.frame.size.height, adView.frame.size.width, 							adView.frame.size.height);

   			}		
		}

So, finally our MainViewController.m will look something like below:

#import "MainViewController.h"

@implementation MainViewController

- (id)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Uncomment to override the CDVCommandDelegateImpl used
        // _commandDelegate = [[MainCommandDelegate alloc] initWithViewController:self];
        // Uncomment to override the CDVCommandQueue used
        // _commandQueue = [[MainCommandQueue alloc] initWithViewController:self];
    }
    return self;
}

- (id)init
{
    self = [super init];
    if (self) {
        // Uncomment to override the CDVCommandDelegateImpl used
        // _commandDelegate = [[MainCommandDelegate alloc] initWithViewController:self];
        // Uncomment to override the CDVCommandQueue used
        // _commandQueue = [[MainCommandQueue alloc] initWithViewController:self];
    }
    return self;
}

- (void)didReceiveMemoryWarning
{
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

#pragma mark View lifecycle

- (void)viewWillAppear:(BOOL)animated
{
    // View defaults to full size.  If you want to customize the view's size, or its subviews (e.g. webView),
    // you can do so here.

    [super viewWillAppear:animated];
}

- (void)viewDidLoad
{
    
    [super viewDidLoad];
    adView.delegate= self;
    
    // Do any additional setup after loading the view from its nib.
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    [adView release];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    // Return YES for supported orientations
    return [super shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}

/* Comment out the block below to over-ride */

/*
- (UIWebView*) newCordovaViewWithFrame:(CGRect)bounds
{
    return[super newCordovaViewWithFrame:bounds];
}
*/

#pragma mark UIWebDelegate implementation

- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
    adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
    
    if([UIApplication sharedApplication].statusBarOrientation ==
       UIInterfaceOrientationPortrait ||
       [UIApplication sharedApplication].statusBarOrientation ==
       UIInterfaceOrientationPortraitUpsideDown) {
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    }
    else {
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
    }
    
    adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    CGRect adFrame = adView.frame;
    adFrame.origin.y = self.view.frame.size.height-adView.frame.size.height;
    adView.frame = adFrame;
    [self.view addSubview:adView];
    // Black base color for background matches the native apps
    theWebView.backgroundColor = [UIColor blackColor];

    return [super webViewDidFinishLoad:theWebView];
}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)newInterfaceOrientation duration:(NSTimeInterval)duration {
    
    BOOL hide = (newInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || newInterfaceOrientation == UIInterfaceOrientationLandscapeRight);
    [[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationNone];
    CGRect mainFrame = [[UIScreen mainScreen] applicationFrame];
    [self.view setFrame:mainFrame];
    
    if (newInterfaceOrientation != UIInterfaceOrientationLandscapeLeft && newInterfaceOrientation != UIInterfaceOrientationLandscapeRight) {
        
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
        [self.view bringSubviewToFront:adView];
        adView.frame = CGRectMake(0.0, self.view.frame.size.height - adView.frame.size.height, adView.frame.size.width, adView.frame.size.height);
        
    }
    
    else {
    
        adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
        [self.view bringSubviewToFront:adView];
        adView.frame = CGRectMake(0.0, self.view.frame.size.width - adView.frame.size.height, adView.frame.size.width, adView.frame.size.height);
        
    }
    
}
/* Comment out the block below to over-ride */

/*

- (void) webViewDidStartLoad:(UIWebView*)theWebView
{
    return [super webViewDidStartLoad:theWebView];
}

- (void) webView:(UIWebView*)theWebView didFailLoadWithError:(NSError*)error
{
    return [super webView:theWebView didFailLoadWithError:error];
}

- (BOOL) webView:(UIWebView*)theWebView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
{
    return [super webView:theWebView shouldStartLoadWithRequest:request navigationType:navigationType];
}
*/

@end

@implementation MainCommandDelegate

/* To override the methods, uncomment the line in the init function(s)
   in MainViewController.m
 */

#pragma mark CDVCommandDelegate implementation

- (id)getCommandInstance:(NSString*)className
{
    return [super getCommandInstance:className];
}

/*
   NOTE: this will only inspect execute calls coming explicitly from native plugins,
   not the commandQueue (from JavaScript). To see execute calls from JavaScript, see
   MainCommandQueue below
*/
- (BOOL)execute:(CDVInvokedUrlCommand*)command
{
    return [super execute:command];
}

- (NSString*)pathForResource:(NSString*)resourcepath;
{
    return [super pathForResource:resourcepath];
}

@end

@implementation MainCommandQueue

/* To override, uncomment the line in the init function(s)
   in MainViewController.m
 */
- (BOOL)execute:(CDVInvokedUrlCommand*)command
{
    return [super execute:command];
}

@end

Summary
The modified MainViewController files integrates the Advertisement view to the Application. With this feature we can target Apple mobile devices like iPhone, iPod Touch and iPad. This feature gives a boost to the in-App advertising, along with improving user interactions. iAd may not show in the simulator sometimes but will definitely work great in device.

Written By: Lopamudra Joshi, Software Developer, Mindfire Solutions

Advertisements

One thought on “Integrating iAd in a PhoneGap Project

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s