Search code examples
iosobjective-cadmobiad

Displaying AdMob and/or iAd when switching tabs using shared banners on iOS


I have an app with a UITabBarController containing 5 tabs, where each tab is a UIViewController with a UITableView embedded in. I am bringing iAds and AdMobs to my app which will be removed using IAP's. This is a universal iPhone and iPad app.

At first, I implemented just the iAds with the use of a Shared Banner and the AppDelegate and it worked really well. Now, before releasing, I am going to also use AdMob banners as a fallback in case an iAd banner doesn't load. I have set it up in the same way as the iAd banners.

Implementing the actual AdMob banners is not a problem in the same way, but I am facing an issue when changing tabs.

Issue

If an iAd banner loads and I move from the first tab to the second tab, it continues to show that iAd banner. If an AdMob banner loads and I move from the first tab to the second tab, the AdMob banner disappears until it loads again.

Code:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    NSLog(@"VIEW WILL APPEAR");
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"IAPSuccessful"])
    {
        NSLog(@"View will appear and the IAP is not Successful");
        [self displayiAdsOrNot];
    }
    else
    {
        NSLog(@"View will appear and the IAP IS Successful");
        self.adBanner.hidden = YES;
        self.adMobBannerView.hidden = YES;
    }
}

- (void)displayiAdsOrNot
{
    NSLog(@"Display iAds or Not");

    self.adMobBannerView.hidden = YES;
    self.adBanner = [[self appdelegate] adBanners];
    self.adBanner.delegate = self;

    if (IDIOM == IPAD)
    {
        NSLog(@"***This is the iPad****");
        [self.adBanner setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height-80, 320, 50)];
        [self.adBanner setTranslatesAutoresizingMaskIntoConstraints:NO];

        [self.view addSubview:self.adBanner];
        NSLayoutConstraint *myConstraint =[NSLayoutConstraint
                                           constraintWithItem:self.adBanner
                                           attribute:NSLayoutAttributeLeading
                                           relatedBy:NSLayoutRelationEqual
                                           toItem:self.view
                                           attribute:NSLayoutAttributeLeading
                                           multiplier:1.0
                                           constant:0];

        [self.view addConstraint:myConstraint];



        myConstraint =[NSLayoutConstraint constraintWithItem:self.adBanner
                                                   attribute:NSLayoutAttributeTrailing
                                                   relatedBy:NSLayoutRelationEqual
                                                      toItem:self.view
                                                   attribute:NSLayoutAttributeTrailing
                                                  multiplier:1
                                                    constant:0];

        [self.view addConstraint:myConstraint];

        myConstraint =[NSLayoutConstraint constraintWithItem:self.adBanner
                                                   attribute:NSLayoutAttributeBottom
                                                   relatedBy:NSLayoutRelationEqual
                                                      toItem:self.view
                                                   attribute:NSLayoutAttributeBottom
                                                  multiplier:1
                                                    constant:0];

        [self.view addConstraint:myConstraint];

    }
    else
    {
        NSLog(@"*** THIS IS THE IPHONE ***");
        [self.adBanner setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height-98, 320, 50)];
        [self.view addSubview:self.adBanner];
    }

}

Delegate methods:

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    NSLog(@"bannerViewDidLoadAd gets called");

    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"IAPSuccessful"])
    {
        NSLog(@"bannerViewDidLoadAd gets called and the IAP is not successful, so we hide the AdMob and show the iAd");
        self.adMobBannerView.hidden = YES;
        self.adBanner.hidden = NO;
    }
    else
    {
        NSLog(@"bannerViewDidLoadAd gets called and the IAP IS Successful so we hide the AdMob and iAd");
        self.adMobBannerView.hidden = YES;
        self.adBanner.hidden = YES;
    }


}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    NSLog(@"The didFailToReceiveAdWithError is called and it is unable to show ads in Timeline. Error: %@ %@", [error localizedDescription], [error domain]);
    self.adBanner.hidden = true; 
    [self displayAdMobBannerOrNot];
}

- (void)displayAdMobBannerOrNot
{
    NSLog(@"DisplayAdMobBannerOrNot is called");
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"IAPSuccessful"])
    {
        NSLog(@"The DisplayAdMonBannerOrNot is called and the IAP is not Successful");
        self.adMobBannerView.hidden = NO;
        self.adMobBannerView = [[self appdelegate] adMobBanners];
        self.adMobBannerView.rootViewController = self;
        self.adMobBannerView.delegate = self;

        self.adMobBannerView.adUnitID = @"ca-app-pub-394025609333333333335716";

        if (IDIOM == IPAD)
        {
            NSLog(@"The DisplayAdMobBannerOrNot is called and we are using an iPad");
            [self.adMobBannerView setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height-80, 320, 50)];
            [self.adMobBannerView setTranslatesAutoresizingMaskIntoConstraints:NO];

            [self.view addSubview:self.adMobBannerView];
            NSLayoutConstraint *myConstraint =[NSLayoutConstraint
                                               constraintWithItem:self.adMobBannerView
                                               attribute:NSLayoutAttributeLeading
                                               relatedBy:NSLayoutRelationEqual
                                               toItem:self.view
                                               attribute:NSLayoutAttributeLeading
                                               multiplier:1.0
                                               constant:0];

            [self.view addConstraint:myConstraint];

            myConstraint =[NSLayoutConstraint constraintWithItem:self.adMobBannerView
                                                       attribute:NSLayoutAttributeTrailing
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:self.view
                                                       attribute:NSLayoutAttributeTrailing
                                                      multiplier:1
                                                        constant:0];

            [self.view addConstraint:myConstraint];

            myConstraint =[NSLayoutConstraint constraintWithItem:self.adMobBannerView
                                                       attribute:NSLayoutAttributeBottom
                                                       relatedBy:NSLayoutRelationEqual
                                                          toItem:self.view
                                                       attribute:NSLayoutAttributeBottom
                                                      multiplier:1
                                                        constant:0];

            [self.view addConstraint:myConstraint];

        }
        else
        {
            NSLog(@"The DisplayAdMobBannerOrNot is called and we are using an iPhone");
            [self.adMobBannerView setFrame:CGRectMake(0, [[UIScreen mainScreen] bounds].size.height-98, 414, 50)];

            [self.view addSubview:self.adMobBannerView];

                GADRequest *request = [GADRequest request];
                request.testDevices = @[ @"151111111111ffb836f4d823ac" ];
                [self.adMobBannerView loadRequest:request];
        }
    }
    else
    {
        NSLog(@"The DisplayAdMobBannerOrNot is called and the IAP IS Successful so we'll just hide the iAd and the adMobBanner");
        self.adBanner.hidden = YES;
        self.adMobBannerView.hidden = YES;
    }
}

So, when the viewWillAppear gets called (every time I come back to this UIViewController), I am checking if the IAPSuccessful BOOL is true. If it's false, I load up the displayiAdsOrNot method. If that fails, it's delegate will get called which calls the displayAdMobBannerOrNot.

Now, I completely understand why, when I have an AdMob banner displaying and I move from one view to another, it removes the AdMob banner because when I come back, the viewWillAppear loads up the Shared Banner for iAd and not AdMob.

With that in mind, I'm not really sure what I need to do. I want to ensure that AdMob is loading the Shared Banner every time it's loaded. So I put the Shared Banner code from the displayAdMobBannerOrNot into the displayiAdOrNot and it didn't change the behavior, because it's not calling the functionality to actually place the ad (displayAdMobBannerOrNot).

As a test, in the viewWillAppear, when the IAPSuccessful is false, I called [self bannerView:self.adBanner didFailToReceiveAdWithError:nil]; instead of anything else and that worked. When I moved from tab one to tab two, it kept the AdMob banner in display. However, that's of course not production code. I'm just not able to see this clearly.


Solution

  • You are hiding your adMobBannerView in your displayiAdsOrNot function. This function is called every time the viewWillAppear. Remove this and you should get the results you desire.

    As for the rest of your code, you have a lot going on here. First, to simplify things you should move all of your code that is creating and laying out your adBanner and adMobBannerView under viewWillAppear when [[NSUserDefaults standardUserDefaults] boolForKey:@"IAPSuccessful"] is false, and set both banners .hidden = YES automatically. This will eliminate the need for your displayiAdsOrNot and displayAdMobBannerOrNot where you are repeating a lot of the same if statements checking for IAP and which device the user is using. After doing this, in your delegate methods you can simply hide or show the correct banner depending on if iAd fails or not now. For example, iAd loads so set its hidden value to NO and AdMob’s to YES, and vice versa if iAd fails to load an ad. I’m sure you were checking the IAP every time in case the user purchased it while in the current session so you could remove the ads. An easier solution would be to move the ads outside of the screen bounds on completion of the IAP and then on the next launch of your application simply do not create either banner at all if [[NSUserDefaults standardUserDefaults] boolForKey:@"IAPSuccessful"] is true. A few other things to point out are, you should remove your request.testDevices AdMob request before submitting your application, and it seems you are defining your NSLayoutConstraint *myConstraint multiple times. I’m not exactly sure what you’re trying to do here. Also, in didFailToReceiveAdWithError you have self.adBanner.hidden = true, it should be self.adBanner.hidden = YES.