iAd implementation

I am going to attempt to show how I implemented iAds in an entire app by using Apple's best practices of only one iAd banner per app.  I have not submitted this method yet, but I get absolutely no errors.  I will be submitting the app that I used this in very shortly and will let you know how it goes.  This method is a combination of things I have tried, and failed at, and things that I have found on SO.  It also includes a great little method to make an iAd stick to the bottom of a UITableView.

Using one ADBannerView in multiple View Controllers.

First you need to import the iAd framework into your project.  Click on your App target in the upper left hand corner of Xcode's left screen.  Under General go down to Linked Frameworks and click on the plus sign.  Then find iAd and add it to your App.

In your AppDelegate header file import iAd.  #import <iAd/iAd.h>  Then after the UIApplicationDelegate add ADBannerViewDelegate.

@interface AppDelegate : UIResponder <UIApplicationDelegate, ADBannerViewDelegate>

This allows the AppDelegate to hold onto the iAd banner for all VC's.  Also, make a property under the UIWindow for a strong, nonatomic ADBannerView.  I called mine *myIAD.  Then make a BOOL, nonatomic, that will let you know if the banner view is visible or not.  I called mine adBannerViewIsVisible.

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) ADBannerView *myIAD;

@property (nonatomic) BOOL adBannerViewIsVisible;

In the AppDelegate implementation file in the method didFinishLauchingWithOption, set your adBannerViewIsVisible to no.

_adBannerViewIsVisible = NO;

Now for the iAd delegate methods, all of these will be in the AppDelegate.m file as well.

#pragma mark iAd methods

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    NSLog(@"bannerViewDidLoadAd");
    
    if (!_adBannerViewIsVisible)
    {
        _adBannerViewIsVisible = YES;
        [_myIAD setAlpha:1.0];
    }
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    NSLog(@"banner didFailToReceive");
    
    if (_adBannerViewIsVisible)
    {
        _adBannerViewIsVisible = NO;
        [_myIAD setAlpha:0.0];
    }
}

- (ADBannerView *)myIAD
{
    if (_myIAD == nil)
    {
        Class classAdBannerView = NSClassFromString(@"ADBannerView");
        
        if (classAdBannerView != nil)
        {
            _myIAD = [[classAdBannerView alloc] initWithFrame:CGRectZero];
            
            // set the frame and change it in other VC's for all possible orientations
            [_myIAD setFrame:CGRectMake(0, self.window.frame.size.height - 114, 320, 50)];
            
            [_myIAD setAlpha:0.0];
            [_myIAD setDelegate:self];
        }
    }
    
    return _myIAD;

}

This makes the one banner you will use for all VC's.

Now whenever you want to use this banner in a VC do the following.

In the .h file, import iAd. #import <iAd/iAd.h>  Then create an outlet for your ADBannerView.  I called mine the same this as I did in my AppDelegate, but you can call it whatever.

@property (strong, nonatomic) ADBannerView *myIAD;

In the .m file, import your AppDelegate.  #import "AppDelegate.h"  And then you will need to get a reference to it.

- (AppDelegate *) appdelegate
{
    return (AppDelegate *)[[UIApplication sharedApplication] delegate];

}

I placed this method right after the viewDidLoad method.  Then in your viewDidAppear method you can create your banner.

First make your local var of iAd (mine is _myIAD) the app delegates iAd.

_myIAD = [[self appdelegate] myIAD];

You then have to add it to your view.

[self.view addSubview:_myIAD];

Now, before you add it to your view, you will have to set it's frame.  This is going to depend on your app and where you want the iAd to appear.  But it will look something like this....

[_myIAD setFrame:CGRectMake(0, _myView.frame.size.height - 32, 480, 32)];

This will get your iAd on screen, but you will have to then manipulate it for rotation and such.  

One this I had a hard time figuring out was what to do with a UITableView.  Because when you add it, the iAd just moves up and down with the tableview.  Not too good!!  So I came across this little snippet on SO.


- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect frame = _myIAD.frame;
    frame.origin.y = _myTableView.contentOffset.y + _myTableView.frame.size.height-_myIAD.frame.size.height; // Move view to the bottom on scroll
    _myIAD.frame = frame;
    [_myTableView bringSubviewToFront:_myIAD];

}

For my rotation, I did register for a notification and it worked like a charm.  So in the viewDidLoad after the call to super I did....


[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateUI:) name:UIDeviceOrientationDidChangeNotification object:nil];


In my method updateUI: I just figured out where the iAd needed to be for each orientation.  It started out like this....


- (void)updateUI:(NSNotification *)note
{

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

etc.etc.

Well, hopefully this will get approved by Apple, I have another app that was approved with iAds, but used a slightly different method, some of which I have implemented here.  But I put this all together so I could stop getting the dreaded Error Domain = ADErrorDomain Code = 7, this ad has been unloaded.  Let me know what you think.


1 comment:

  1. Well, it was finally approved and the ads are running!! So this method does work. Best of luck to you all in your own implementation of iAds.

    ReplyDelete