【问题标题】:Test iAds are good, but live iAds fail测试 iAd 很好,但实时 iAd 失败
【发布时间】:2014-04-26 06:30:01
【问题描述】:

当我的应用程序处于开发阶段时,iAds 效果很好。每隔 30 秒,我就会接到“bannerViewDidLoadAd”或“didFailToReceiveAdWithError”的电话,我准备应用程序来处理任一回调。我得到绿色复选标记“您已连接到 iAd 的应用网络”和其他测试广告。

现在该应用已上线,它只会收到“didFailToReceiveAdWithError”并且永远不会加载广告。 我在插入 Xcode Organizer Console 的手机上运行已发布的应用程序版本,我看到在“didFailToReceiveAdWithError”中打印的 NSLog

虽然 iAd 门户没有显示任何请求,但它列出了 0 个请求。

我已经使用开发配置文件从 XCode 再次将它构建到我的手机中,并且它再次正常工作。我删除了该应用,关闭了手机,退出了我的 iTunes Apple ID,然后从 App Store 重新下载了该应用,但每次广告仍然失败。

我是这样对广告进行编码的:

在我的 rootViewController 中,用户选择开始一个新游戏,我为新视图设置动画:

    UIViewController *nextController = [[GamePlayViewController alloc] initWithNibName:@"GamePlayView" bundle:nil];
    [nextController performSelector:@selector(setDelegate:) withObject:self];

    nextController.view.frame = CGRectMake(0, 570, 320, 568);
    [self.view addSubview:nextController.view];

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
    [UIView setAnimationDuration:0.23];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    nextController.view.frame = CGRectMake(0, 0, 320, 568);

    [UIView commitAnimations];

    temporaryController = nextController;

GamePlayViewController.h 包括:

 - #import <iAd/iAd.h>
 - @interface GamePlayViewController : UIViewController <ADBannerViewDelegate, UIDocumentInteractionControllerDelegate> {

GamePlayViewController.m 包括:

 - ADBannerView *_bannerView;

一旦用户进入 GamePlayViewController.m,就会在 viewDidLoad 中触发一个动画,一旦该动画完成,就会调用一个广告:

if ([ADBannerView instancesRespondToSelector:@selector(initWithAdType:)]) {
        _bannerView = [[ADBannerView alloc] initWithAdType:ADAdTypeBanner];
    } else {
        _bannerView = [[ADBannerView alloc] init];
    }
    _bannerView.delegate = self;

    [self.view bringSubviewToFront:_bannerView];
}

除了 iAds 的回调方法之外,这就是它的全部内容。

- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
    NSLog(@"ad loaded!");

    _bannerView.hidden = NO;
    [self layoutAnimated:YES];
}

- (void)layoutAnimated:(BOOL)animated
{
    // As of iOS 6.0, the banner will automatically resize itself based on its width.
    // To support iOS 5.0 however, we continue to set the currentContentSizeIdentifier appropriately.
    CGRect contentFrame = self.view.bounds;
    if (contentFrame.size.width < contentFrame.size.height) {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
    } else {
        _bannerView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
    }

    CGRect bannerFrame = _bannerView.frame;
    if (_bannerView.bannerLoaded) {
        bannerFrame.origin.y = 0;
    } else {
        bannerFrame.origin.y = contentFrame.size.height;
    }


    [UIView animateWithDuration:animated ? 0.25 : 0.0 animations:^{
        _contentView.frame = contentFrame;
        [_contentView layoutIfNeeded];
        _bannerView.frame = bannerFrame;
        [self.view addSubview:_bannerView];
    }];
}

- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
    NSLog(@"ad failed!");
    _bannerView.hidden = YES;
}

也许我做错了什么,或者我应该在 rootViewController 本身上放置广告,但这段代码在测试 iAd 上效果很好,所以我不确定为什么它不适用于应用程序的 App Store 版本。

感谢您的帮助!

【问题讨论】:

    标签: ios iphone objective-c iad


    【解决方案1】:

    我没有查看您的代码,但我也观察到了这一点。有时,Apple 只是没有出售任何广告,因此没有任何广告可供您展示。考虑使用广告聚合器。我使用https://github.com/larsacus/LARSAdController,但对其进行了修改以按照我想要的方式展示广告。

    我在我的博客文章中介绍了这一点:http://www.notthepainter.com/iad-admob-integration-with-a-dynamic-uiview/


    这是博客条目的文本,因此保留在这里,以防我的博客有一天会消失。


    我已经发布了 2 个带有 iAds 的应用程序。我使用 Apple 的 BannerView 示例代码来实现这一点。基本上,在您的委托中,您不会将 root 设置为您预期的 root UIViewController,而是将 root 设置为包含您真正的 root 的 BannerView。当 iAd 可用时,您的主视图会缩小并且 iAd 显示在底部。当广告不可用时,您的视图会扩大到其“正常”尺寸。

    这在测试中非常有效,因此我将这两个应用程序都发布到了应用商店。他们完成了吗?和惠林。然而,当我第一次从商店下载这些版本时,我很惊讶地发现从来没有广告。事实证明,至少现在,iAd 的填充率非常糟糕。所以我想在 iAd 不可用时再展示一个广告。

    我在 GitHub 上找到了 larsacus 的开源项目 LARSAdController。除了一件事,他使广告集成变得非常容易。当你沿着他的快速发展路线走时,你会看到广告覆盖你的视野,它不会缩小以适应广告。这是一个完全合理的设计决定,而不是我想要的。

    所以我决定修改 Apple 的 BannerView 以使用 LARSAdController。这很容易。

    您要做的第一件事是从 BannerView 的 .h 文件中删除 iAd 并在 LARS TOLAdViewController 类中删除广告。

    #import "TOLAdViewController.h"
    
    #define KVO_AD_VISIBLE @"KVO_AD_VISIBLE"
    
    @interface BannerViewController : TOLAdViewController
    

    (暂时忽略 KVO_AD_VISIBLE 定义,稍后我会介绍。)在 .m 文件中还删除 iAd 并进行以下更改:

    @implementation BannerViewController {
        UIView *_bannerView;
        UIViewController *_contentController;
        BOOL isLoaded;
    }
    

    我们将 _bannerView 从 ADBannerView 更改为普通的旧 UIVIew。 ADBannerView 还有一个bannerLoaded 属性,我们必须用我们的isLoaded 布尔值替换它。 initWithContentViewController 也很容易修改。

    // IAPHelper *sharedInstance = [//IAPHelper sharedInstance];
    //if ([sharedInstance showBannerAds]) {
    if (YES) {
        _bannerView = [[UIView alloc] initWithFrame:CGRectZero];
    } else {
        _bannerView = nil;      // not showing ads since the user has upgraded
    }
    

    注意注释掉的部分。如果您使用应用内购买将支持广告的版本转换为无广告版本,您可以在此处进行操作。

    在该方法的最后,使用 Key-Value-Observing (KVO) 观察 LARS 并查看何时投放或删除广告。 (我可能会在以后的博客文章中介绍 KVO。)

    [[LARSAdController sharedManager] addObserver:self
                                       forKeyPath:kLARSAdObserverKeyPathIsAdVisible
                                          options:0
                                          context:KVO_AD_VISIBLE];
    

    以及观察代码:

    - (void)observeValueForKeyPath:(NSString *)keyPath
                          ofObject:(id)object
                            change:(NSDictionary *)change
                           context:(void *)context;
    {
        if(context == KVO_AD_VISIBLE) {
            NSNumber *isVisible = [object valueForKey:kLARSAdObserverKeyPathIsAdVisible];
    
            if ([isVisible boolValue]) {
                _bannerView.frame = [[LARSAdController sharedManager] containerView].frame;
                isLoaded = YES;
            } else {
                isLoaded = NO;
            }
        }
    
        [self.view setNeedsLayout];
        [self.view layoutIfNeeded];
    }
    

    我们保存新广告的框架并更新 isLoaded 变量。 (原本以为我需要调用 setNeedsLayout 和 layoutIfNeeded,但实际上我没有。) viewDidLayoutSubviews 的模组也非常简单。唯一奇怪的部分是删除了对 ADBannerContentSizeIdentifierPortrait 和 ADBannerContentSizeIdentifierLandscape 的引用,并将其全部替换为一行:

    bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
    

    几行之后你使用新的 isLoaded 变量

    if (isLoaded) {
    

    别忘了在 dealloc 中清理你的观察者:

    -(void) dealloc;
    {
        [[LARSAdController sharedManager]  removeObserver:self forKeyPath:kLARSAdObserverKeyPathIsAdVisible];
    }
    

    剩下的就是在你的应用代理中告诉 LARS 你的广告:

    [[LARSAdController sharedManager] registerAdClass:[TOLAdAdapterGoogleAds class] withPublisherId:@"a14e55c99c24b43"];
    [[LARSAdController sharedManager] registerAdClass:[TOLAdAdapteriAds class]];
    
    LARSBannerViewController *root = [[LARSBannerViewController alloc] initWithNibName:@"LARSBannerViewController" bundle:nil];
    
    _bannerViewController = [[BannerViewController alloc] initWithContentViewController:root];
    
    [self.window setRootViewController:_bannerViewController];
    

    就是这样。现在您的应用应该会显示 iAD 或 AdMob 广告,并且您的视图会缩小以适应它们。

    当然有一个错误,我不知道这是在 AdMob 服务器中还是在 LARS 中,但是当您在 iPhone 上处于横向模式时,广告的尺寸和报告的尺寸不同,会在底部留下一个黑条屏幕。我已经 ping 过 larsacus,当我知道更多信息时会更新这篇文章。

    我已经 fork LARSAdController 并将上述示例代码提交到我的 github 上的一个完整项目中。

    【讨论】:

    • 谢谢...我会看看这个,我过去使用过 adwhirl,但我想我会简化并只在这个应用程序上使用 iAd。如果 Apple 没有为我展示广告,iAd 门户是否仍会显示大量请求和 0% 的填充率?它根本没有显示任何请求,而且我看到 iAd 在其他公司的应用程序中加载得很好......
    • 这确实很奇怪,是的。
    【解决方案2】:

    几天后,我准备打电话寻求支持,然后 iAd 开始工作。所以我想答案是,在应用上线和为该应用填充广告之间可能会出现延迟。

    刚开始投放广告时,填充率并没有超过 50%,我只看到 iTunes Radio 的一则广告,但至少广告已经开始发挥作用。现在填充率高达 67%,而且我看到广告的种类更多了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多