AdMob 刷新请求

AdMob Refresh Requests

我有几个问题很困惑:

  1. 谁最负责广告刷新?在我加载请求后 bannerView.load(GADRequest()) 让开发人员或 Google 监控它是最佳做法吗?

  2. 刷新时间应该短至 30 秒还是至少 60 秒?他们建议 60 秒,但让您可以选择 30 秒,这似乎很奇怪。我在不同的话题上读到过,您可能会因各种各样的事情而受到惩罚,并且您的 AdMob 帐户将在没有任何问题的情况下被关闭。如果是这种情况,如果您在控制台中选择 30 秒,他们建议 60 秒,如果他们觉得有任何问题 "funny",他们可以仅凭这一点就终止您的帐户。这是一个非常倾斜的过程。

  3. 它说如果您的应用自动刷新广告,请确保在屏幕关闭时不发出广告请求。如果我的第一个问题的答案是让 Google monitor/automatically 刷新(不使用我下面的代码),Google 怎么知道屏幕是否关闭?例如,广告显示在 viewControllerA 中,但用户按下按钮并按下 viewControllerB。由于 viewControllerA 仍在堆栈中,广告将不断刷新,我不明白 Google 如何知道屏幕已关闭,直到 viewControllerA 被解除分配。另外,如果用户进入后台,Google 怎么知道?我假设 off 意味着用户无法再看到屏幕,这意味着他们看不到广告,因此无需刷新,因为他们要么切换标签,要么推到另一个 VC,或者进入后台(下面代码处理的所有情况)

  4. 刷新控制台页面的link在哪里?在您可以转到 https://apps.admob.com > Monetize 之前,您最终会进入带有刷新选项的页面。当我登录时,我不再看到货币化选项,而是看到一个带有一堆图标的侧边栏。 None 个图标将我带到刷新页面。仅供参考,我昨天才开始使用 AdMob,我只在视频和在线教程中看到刷新页面,所以我以前从未使用过它。

它说 here(强调我的):

Refreshing ads

We recommend that you have ads persist for 60 seconds or longer, depending on the functionality of your app. Our internal tests have shown that this ensures users have enough time to engage with ads, providing the best performance for both advertisers and publishers. Furthermore, these tests have shown that refreshing ads more often can hurt fill rate for our publishers.

If your app is automatically refreshing ads, make sure ad requests are not made when the screen is off. Also, if users navigate to and from pages with ads in an app over a short period of time, a new ad request should not be made sooner than the recommended 60 second rate.

但它也说 here:

Banner ads

We recommend using the Google-optimized automatic refresh rate. The optimized rate is calculated using AdMob historical data to ensure the ads shown in your ad units are being refreshed at the best rate for banner ads.

You may also set a custom refresh rate of 30-120 seconds or disable refresh rate completely.

以下是我每 30 秒自己管理一次请求的方式,考虑到用户何时进入后台、切换选项卡或按下另一个 VC。如果我不做所有这些并留给他们 ("We recommend using the Google-optimized automatic refresh rate"),Google 怎么知道屏幕是否关闭?

var timer: Timer?

override viewDidLoad() {
    super.viewDidLoad()

    // instantiate bannerView ...

    NotificationCenter.default.addObserver(self, selector: #selector(startAdRefreshTimer), name: UIApplication.willEnterForegroundNotification, object: nil)

    // *** the screen is OFF
    NotificationCenter.default.addObserver(self, selector: #selector(stopAdRefreshTimer), name: UIApplication.willResignActiveNotification, object: nil)
}

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        startAdRefreshTimer()
}

// *** the screen is OFF
override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        stopAdRefreshTimer()
}

@objc func startAdRefreshTimer() {

    timer?.invalidate()
    timer = Timer.scheduledTimer(withTimeInterval: 30,
                                 repeats: true,
                                 block: { [weak self](timer) in
                                            self?.refreshAd()
    })
}

func refreshAd() {

    bannerView.load(GADRequest())
}


@objc func stopAdRefreshTimer() {
    if timer != nil {
        timer?.invalidate()
        timer = nil
    }
}

// this really isn't necessary because of what's in viewWillDisappear but I added it anyway
@objc func buttonToPushNextVCTapped() {

    let nextVC = NextVC()
    navigationController?.pushViewController(viewController: nextVC, animated: true, completion: { [weak self] in

        // *** the screen is OFF
        self?.stopAdRefreshTimer()
    })
}

这不是完美的解决方案,因为如果用户快速且反复地来回切换标签页,请求将在 30 秒之后发生,这可能会导致您的帐户被禁止。这仅用于示例目的。

我认为您会在 AdMob 横幅广告中发现许多令人困惑的东西。为了确定广告的网络调用发生了什么,我不得不使用 Charles 代理来监控网络流。我找不到任何证据表明横幅在任何不在堆栈顶部的视图上继续请求广告。但是,我没有深入研究框架来找出 how/why 因为我试图解决另一个问题。我建议只允许 Admob 使用其股票代码存根按时间投放广告:

bannerView = GADBannerView(adSize: kGADAdSizeBanner)
addBannerViewToView(bannerView)

我还向委托函数添加了一些调试代码 adViewDidReceiveAd(_ bannerView: GADBannerView) 以确保当视图不在堆栈顶部时我的应用程序不会投放广告。找不到任何证据。

最后,强烈建议永远不要使用生产广告进行测试,并坚持不懈地遵循他们在 VC 中的广告放置方面的最佳做法,以免接触或以其他方式直接靠近其他可操作对象。很可能您会被关进 AdMob 监狱,并且数周或更长时间都不知道(只有广告会停止投放,您会收到可怕的代码 1 "No Ad to Show" 调试消息)。

回答我的第一个、第二个和第三个问题:

1st 这是我的 which seems to be totally fine。我也在使用 TabBarController。顺便说一下,collectionView 在 vc 中处理 bannerViewload(GADRequest())。 headerView 只显示广告,所以我不必担心它会在用户滚动时不断被调用并且 headerView 会被回收。您可以阅读我的设置中的link了解更多详情。

第二个 AdMob 的 BannerView 有一个 delegate method 在收到新广告时被调用:

MyController: GADBannerViewDelegate {

    /// Tells the delegate an ad request loaded an ad.
    func adViewDidReceiveAd(_ bannerView: GADBannerView) {
        print("adViewDidReceiveAd")
    }
}

第三。我在该打印语句上放置了一个断点以查看会发生什么,结果如下。

  1. 当我让 headerView 可见(没有将它滚动到场景外)时,委托方法每 60 秒触发一次。我可能会在几秒钟前停下来,因为我看了看电脑上的时间,但没有使用计时器。无论如何,几乎每 60 秒就会触发断点并更改测试广告。

  2. 当我将 headerView 滚动到场景之外并等待断点时,断点从未被击中,这意味着委托方法从未被调用。我等了 10 分钟,什么也没发生 - 没有投放任何广告。

  3. 当我将 headerView 滚动回场景时,我等待了几秒钟,最终命中断点,这意味着调用了委托。就像在第一个场景中一样,它之后每 60 秒就会被击中一次。

  4. 我切换到另一个选项卡,离开几分钟,发生了 #2 中的完全相同的事情,因为没有调用委托,所以没有击中断点。

  5. 当我回到带有 headerView 的选项卡时,#3 中发生了同样的事情,每 60 秒触发一次断点,因为调用了委托。

  6. 我去了后台,再次像#2 断点没有被击中,因为没有调用委托。

  7. 当我像#3 一样从后台返回时,断点每 60 秒触发一次,因为委托被调用了。

我的结论是 bannerView 绝对知道 它何时不在场景中。如果更改了选项卡,应用程序将进入后台(可能使用通知),最神秘的是它甚至知道它何时是另一个视图的子视图并且该视图滚动 on/off 场景。

我在纽约布朗克斯区,现在是早上 8 点(我在早上 7 点左右开始测试),广告基本上每 60 秒更换一次。也许在世界其他地方,一天中的不同时间,或一年中的不同时间,持续时间可能更长或更短?

根据我现在所知道的,我认为最好让 Google 监控 load(GADRequest()) 并在准备就绪时更改广告。每 60 秒更换一次广告对我来说没问题。如果场景可以吸引用户的注意力超过一分钟,即投放了 2 个广告。这更有用,因为我可以花更多的时间来吸引他们的注意力,而不是专注于为他们投放广告。

就我问题中处理所有 off 情况的代码而言,bannerView 似乎能够自行处理所有这些情况。它减少了我维护和处理的代码,更重要的是,它减少了 1 个担心因处理不当而被禁止的理由。

总结(这最适合我)

  1. 让 Google handle/monitor bannerView.load(GADRequest()) 投放新闻广告

  2. 不要自定义刷新,它似乎每 60 秒自动更改一次

  3. 使用 bannerView 时(并且可能让 Google 监控 load(GADRequest())) 当屏幕 关闭时不请求广告所以不必浪费时间担心它

第 4 个问题的答案:

打开 App Refresh 的货币化页面似乎不再存在。登录 AdMob 后,请执行以下 5 个步骤(在第 2 步中点击蓝色广告单元名称后,第 3、4 和 5 步将出现一个新屏幕)。