Использование iAds на iPad дает сбой после огромного количества вызовов bannerView:didFailToReceiveAdWithError:

У меня есть приложение, которое использует AdBannerView, определенный xib. Если приложение работает на iPhone (4 или 5), все работает как положено, показывается реклама, скрываются/показываются баннеры и т. д.

Однако, если приложение запущено на iPad, оно аварийно завершает работу из-за того, что не может получить рекламу. Изучение стека вызовов показывает повторяющиеся вызовы bannerView:didFailToReceiveAdWithError:

Наблюдение за распределением памяти во время работы на iPad показывает непрерывный рост памяти вплоть до сбоя.

Игра с сетевым подключением, похоже, не меняет того факта, что он работает на iPhone, но не на iPad.

Я прочитал этот вопрос SO, который вместо использования AdBannerView в xib он создает его на лету, а затем выпускает, когда объявление не загружается.

ИЗМЕНИТЬ:

Я изменил настройки устройств в файле проекта с iPhone на Universal. Приложение теперь не вылетает, но, конечно, все представления теперь «перепутались». Таким образом, одним из вариантов исправления может быть внедрение идиомы iPad во всем приложении.

Мои вопросы -

  1. Что здесь происходит? Нет, правда! Я не понимаю, почему разные устройства ведут себя по-разному.

  2. Должен ли я создавать AdBannerView программно? Похоже на пораженчество.

  3. Как я могу исправить это поведение?

Вот код

#pragma mark ADBannerViewDelegate

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    [self showBanner];
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    [self hideBanner];
}

- (void)bannerViewActionDidFinish:(ADBannerView *)banner
{
    [self hideBanner];
}

#pragma mark ADBanner helpers

- (void)hideBanner
{
    CGRect hiddenFrame = self.bannerDisplayFrame;
    hiddenFrame.origin.y = self.view.frame.size.height;

    [UIView animateWithDuration:0.3f
                     animations:^{
                         [self.adBannerView setFrame:hiddenFrame];
                     }
                     completion:^(BOOL finished)
                     {
                         if (finished)
                         {
                             [self.adBannerView setAlpha:0.0f];
                         }
                     }];
}

- (void)showBanner
{
    [self.adBannerView setAlpha:1.0f];
    [UIView animateWithDuration:0.3f
                     animations:^{
                         [self.adBannerView setFrame:self.bannerDisplayFrame];
                     }
                     completion:^(BOOL finished)
                     {
                         if (finished)
                         {
                             [NSTimer scheduledTimerWithTimeInterval:60.0f target:self selector:@selector(hideBanner) userInfo:nil repeats:NO];
                         }
                     }];

}

person Damo    schedule 09.05.2013    source источник
comment
ваше приложение универсально?   -  person ignotusverum    schedule 10.05.2013
comment
Он установлен для iPhone. Но оно было отклонено Apple, и они заявили, что протестировали его на iPad, и оно вышло из строя. Я проверил, и да, это действительно сбой!   -  person Damo    schedule 10.05.2013
comment
проверьте это stackoverflow.com/questions/10243188/iad- не работает на iPad.   -  person ignotusverum    schedule 10.05.2013
comment
Хорошо, теперь он работает, но, очевидно, мои XIB не учитывают идиому iPad. Хороший крик, если ничего не помогает, я знаю, что могу сделать это универсальным приложением. Добавлю комментарий к вопросу.   -  person Damo    schedule 10.05.2013


Ответы (3)


Похоже, вы каждый раз создаете новые виды баннеров iAD, предлагаемый способ — использовать общий вид во всем приложении. Это может быть причиной постоянного увеличения памяти в вашем приложении, и вы обязательно получите предупреждение от серверов Apple, если будете запрашивать рекламу слишком много раз. Подробнее см. здесь в документации Apple Рекомендации iAD

Вот как я реализовал общий рекламный баннер, это может помочь.

AppDelegate.h

@property (nonatomic, strong) ADBannerView *adBanner;

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    ...
    adBanner = [[ADBannerView alloc] initWithFrame:CGRectZero];
    adBanner.delegate = self;
    adBanner.backgroundColor = [UIColor clearColor];
    adBanner.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleTopMargin;
    ...
}

prefix.pch или лучше в заголовочном файле, включенном в prefix.pch

#define SharedAdBannerView ((AppDelegate *)[[UIApplication sharedApplication] delegate]).adBanner

И у меня есть категория uiviewcontroller для обработки iAD.

@implementation UIViewController (SupportIAD)

-(void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    SharedAdBannerView.hidden = FALSE;
}

-(void) bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    SharedAdBannerView.hidden = TRUE;
}

//This method adds shared adbannerview to the current view and sets its location to bottom of screen
//Should work on all devices
-(void) addADBannerViewToBottom
{
    SharedAdBannerView.delegate = self;
    //Position banner just below the screen
    SharedAdBannerView.frame = CGRectMake(0, self.view.bounds.size.height, 0, 0);
    //Height will be automatically set, raise the view by its own height
    SharedAdBannerView.frame = CGRectOffset(SharedAdBannerView.frame, 0, -SharedAdBannerView.frame.size.height);
    [self.view addSubview:SharedAdBannerView];
}

-(void) removeADBannerView
{
    SharedAdBannerView.delegate = nil;
    [SharedAdBannerView removeFromSuperview];
}

@end

А теперь в каждом вьюконтроллере, который будет отображать iAD, импортируйте категорию и в viewDidLoad:

- (void)viewDidLoad
{
    ...
    [self removeADBannerView];
    [self addADBannerViewToBottom];
    ...
}
person guenis    schedule 11.05.2013
comment
Я принял к сведению некоторые из ваших рекомендаций, а именно - иметь только один AdBannerView и создавать его динамически, а не в разных XIB. Есть и другие вопросы, например, почему эта проблема возникает на iPad, а не на iPhone, и я еще не получил разумного объяснения ни от кого, хотя в одном из комментариев говорится о том, чтобы сделать приложение универсальным, что было одновременно полезным и раздражающим! +некоторые баллы за вашу помощь большое спасибо. - person Damo; 17.05.2013

Чтобы предотвратить перепутывание представлений, попробуйте отключить «Автомакет».

Xcode 4.5 портит XIB?

person Totoro    schedule 13.05.2013

Я решил эту проблему.

Корень проблемы заключается в том, что свойство view iPad UIViewController рекурсивно зацикливается.

Все, что вам нужно, это разорвать бесконечный вызов. введите здесь описание изображения

В моем случае я просто добавляю эти строки:

if (_banner.alpha == 0)
{
    return;
}

в методе скрытия баннера.

Я думаю, у вас есть сбой здесь:

hiddenFrame.origin.y = self.view.frame.size.height;

В любом случае, это не очень хороший подход - не проверять свойство перед изменением.

person Mike Glukhov    schedule 24.09.2014