4

I'm working with the Google Mobile Ads SDK on iOS and trying to display some ads. My code:

GADBannerView* bannerView = [[GADBannerView alloc] initWithAdSize:GADAdSizeFromCGSize(CGSizeMake(300, 250))];
bannerView.adUnitID = @"hidden";
bannerView.rootViewController = self;
bannerView.delegate = self;

GADRequest* request = [GADRequest request];
request.testDevices = @[ kGADSimulatorID ];

[bannerView loadRequest:request];

This works fine if I add the bannerView to the view hierarchy right after the code you see above. However, I don't really want to add it until the ad is loaded, so I wanted to delay it. I noticed that if the bannerView is not in the view hierarchy, the delegate methods are not called at all. Furthermore, I have found this answer, which is in line with what I'm observing. On the other hand, this is a quote from the GADBannerViewDelegate header:

/// Tells the delegate that an ad request successfully received an ad. The delegate may want to add
/// the banner view to the view hierarchy if it hasn't been added yet.
- (void)adViewDidReceiveAd:(GADBannerView *)bannerView;

This suggests that it should be possible to receive those delegate callbacks even if the view is not in the hierarchy, which is exactly what I want. So, any ideas how could I achieve this?

Community
  • 1
  • 1
lawicko
  • 7,246
  • 3
  • 37
  • 49
  • You've added the `GADBannerViewDelegate` to your `ViewController`, correct? For example, `@interface ViewController () `. – Daniel Storm Jun 10 '16 at 19:55
  • 1
    @Daniel Yes, I have declared my view controller to implement the protocol, and I don't get any warnings. – lawicko Jun 11 '16 at 11:17

3 Answers3

7

Ok, so the problem here was that I didn't keep the reference to the bannerView. It was deallocated after the method returned, and this is why the delegate methods were not called.

lawicko
  • 7,246
  • 3
  • 37
  • 49
6

I just had the same issue after upgrading from the Admob SDK 7.56 to 8.2:

They changed the method names of the GADBannerViewDelegate protocol.
E.g. instead of

-(void)adViewDidReceiveAd:(GADBannerView *)adView;

it is now

-(void)bannerViewDidReceiveAd:(GADBannerView *)bannerView;

see also the migration guide to Admob SDK version 8:
https://developers.google.com/admob/ios/migration#methods_removedreplaced

Volker Voecking
  • 5,203
  • 2
  • 38
  • 35
0

You should add the GADBannerView to your view and set its hidden property to YES initially. Also, I'd suggest using the AdSize Constant kGADAdSizeBanner that AdMob provides. Here's a list of additional AdSize Constants.

For example:

bannerView = [[GADBannerView alloc] initWithAdSize:kGADAdSizeBanner];
bannerView.adUnitID = @"YourAdUnitID";
bannerView.rootViewController = self;
bannerView.delegate = self;
[bannerView loadRequest:[GADRequest request]];
bannerView.hidden = YES; // Hide banner initially
[self.view addSubview:bannerView];
// This will put the banner at the bottom of the screen and stretch to fit the screens width
[bannerView setFrame:CGRectMake(0, self.view.frame.size.height - bannerView.frame.size.height, self.view.frame.size.width, bannerView.frame.size.height)];

Then, when you receive an ad you unhide the banner. For example:

-(void)adViewDidReceiveAd:(GADBannerView *)adView {
    // We've received an ad so lets show the banner
    bannerView.hidden = NO;
    NSLog(@"adViewDidReceiveAd");
}

-(void)adView:(GADBannerView *)adView didFailToReceiveAdWithError:(GADRequestError *)error {
    // Failed to receive an ad from AdMob so lets hide the banner
    bannerView.hidden = YES;
    NSLog(@"adView:didFailToReceiveAdWithError: %@", [error localizedDescription]);
}

You could also animate this, if you'd prefer, by setting the banner's alpha property to 0.0 initially instead of using it's hidden property. Then, animate the alpha when you receive an ad. For example:

-(void)adViewDidReceiveAd:(GADBannerView *)adView {
    // We've received an ad so lets fade in the banner
    [UIView animateWithDuration:0.2 animations:^{
        bannerView.alpha = 1.0;
    }];
    NSLog(@"adViewDidReceiveAd");
}

-(void)adView:(GADBannerView *)adView didFailToReceiveAdWithError:(GADRequestError *)error {
    // Failed to receive an ad from AdMob so lets fade out the banner
    [UIView animateWithDuration:0.2 animations:^{
        bannerView.alpha = 0.0;
    }];
    NSLog(@"adView:didFailToReceiveAdWithError: %@", [error localizedDescription]);
}

Also, as a side note, the GADBannerView is transparent when there is no ad to display. So, adding it to your view and doing nothing else would work too.

Daniel Storm
  • 18,301
  • 9
  • 84
  • 152
  • Thanks for the answer, but I don't want to add the view to the hierarchy, in fact I want to avoid it at all cost, because this banner is a cell in the collection view, so if it's not loaded, I'm not interested in it. Also, the size is defined to 300x250 so the size constants are of no use to me. 300x250, or so called medium rectangle is pretty popular so I don't worry about lack of ads to display. – lawicko Jun 11 '16 at 11:22
  • @lawicko My pleasure. you should edit your question to include this information. – Daniel Storm Jun 11 '16 at 13:27
  • You mentioned that the banner view "Should" be in the view hierarchy initially. The SDK docs clearly state you may request for it before adding it to the hierarchy. – Eric Alford Oct 04 '16 at 21:09