Методы делегата GADBannerView не вызываются, если представление не находится в иерархии представлений.

Я работаю с Google Mobile Ads SDK на iOS и пытаюсь показать некоторые объявления. Мой код:

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];

Это прекрасно работает, если я добавлю bannerView в иерархию представлений сразу после кода, который вы видите выше. Однако я действительно не хочу добавлять его, пока объявление не загрузится, поэтому я хотел отложить его. Я заметил, что если bannerView не находится в иерархии представлений, методы делегата вообще не вызываются. Кроме того, я нашел этот ответ, что соответствует тому, что я наблюдаю. С другой стороны, это цитата из заголовка GADBannerViewDelegate:

/// 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;

Это говорит о том, что должна быть возможность получать эти обратные вызовы делегата, даже если представление не находится в иерархии, а это именно то, что я хочу. Итак, есть идеи, как я могу этого добиться?


person lawicko    schedule 10.06.2016    source источник
comment
Вы добавили GADBannerViewDelegate к ViewController, верно? Например, @interface ViewController () <GADBannerViewDelegate>.   -  person Daniel Storm    schedule 10.06.2016
comment
@Daniel Да, я объявил свой контроллер представления для реализации протокола и не получаю никаких предупреждений.   -  person lawicko    schedule 11.06.2016


Ответы (3)


Итак, проблема в том, что я не сохранил ссылку на файл bannerView. Он был освобожден после возврата метода, поэтому методы делегата не вызывались.

person lawicko    schedule 02.07.2016

У меня была такая же проблема после обновления Admob SDK 7.56 до 8.2:

Они изменили имена методов протокола GADBannerViewDelegate.
Например. вместо

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

сейчас

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

см. также руководство по переходу на Admob SDK версии 8:
https://developers.google.com/admob/ios/migration#methods_removedreplaced

person Volker Voecking    schedule 18.03.2021
comment
Я ЛЮБЛЮ ВАС!!!!! - person Rajeev Bhatia; 14.04.2021
comment
Теперь после переименования работает, спасибо, странно, что компилятор об этом не предупредил? - person 7RedBits.com; 06.05.2021

Вы должны добавить GADBannerView к своему представлению и изначально установить для его скрытого свойства значение YES. Кроме того, я бы предложил использовать константу AdSize kGADAdSizeBanner, которую предоставляет AdMob. Ниже приведен список дополнительных констант AdSize.

Например:

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)];

Затем, когда вы получаете объявление, вы показываете баннер. Например:

-(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]);
}

Вы также можете анимировать это, если хотите, сначала установив для свойства alpha баннера значение 0.0 вместо использования его свойства hidden. Затем анимируйте alpha при получении объявления. Например:

-(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]);
}

Кроме того, в качестве примечания, GADBannerView прозрачен, когда нет рекламы для отображения. Таким образом, добавление его в ваше представление и ничего больше не будет работать.

person Daniel Storm    schedule 10.06.2016
comment
Спасибо за ответ, но я не хочу добавлять представление в иерархию, на самом деле я хочу избежать этого любой ценой, потому что этот баннер является ячейкой в ​​представлении коллекции, поэтому, если он не загружен, я не заинтересован в этом. Кроме того, размер определен как 300x250, поэтому константы размера для меня бесполезны. 300x250, или так называемый средний прямоугольник, довольно популярен, поэтому я не беспокоюсь о нехватке рекламы для показа. - person lawicko; 11.06.2016
comment
@lawicko С удовольствием. вы должны отредактировать свой вопрос, чтобы включить эту информацию. - person Daniel Storm; 11.06.2016
comment
Вы упомянули, что представление баннера изначально должно быть в иерархии представлений. В документах SDK четко указано, что вы можете запросить его перед добавлением в иерархию. - person Eric Alford; 05.10.2016