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.
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
.