Swift SpriteKit游戏中AdMob Banner Ad无法显示的问题排查
AdMob横幅广告在SpriteKit中无法显示的问题排查与修复
问题描述
使用SpriteKit的GameScene开发游戏,集成AdMob横幅广告时无法显示,调用showBannerAd()时控制台输出No ad ready to be displayed.。广告单元创建超过24小时,App ID正确,插页广告可正常运行。相关代码如下:
import SpriteKit import GameplayKit import GameKit // AdMob import GoogleMobileAds import UIKit class GameScene: SKScene, SKPhysicsContactDelegate, CheckboxNodeDelegate, GKGameCenterControllerDelegate, GADFullScreenContentDelegate, GADBannerViewDelegate { var bannerView: GADBannerView! var isBannerAdReady = false override func didMove(to view: SKView) { ... loadBannerAd() } func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { print("Failed to load banner ad: \(error.localizedDescription)") isBannerAdReady = false } func loadBannerAd() { // bannerView = GADBannerView(adSize: kGADAdSizeBanner) bannerView = GADBannerView(adSize: GADAdSizeFromCGSize(CGSize(width: 320, height: 50))) // Adjust the size as per your requirements bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716" // Replace with your own ad unit ID bannerView.rootViewController = self.view?.window?.rootViewController bannerView.delegate = self bannerView.load(GADRequest()) // showBannerAd() } func showBannerAd() { if isBannerAdReady { self.view?.addSubview(bannerView) isBannerAdReady = false // Set the flag to false after showing the ad } else { print("No ad ready to be displayed.") } } // Tells the delegate that a full-screen view will be presented in response to the user clicking on an ad. func adViewWillPresentScreen(_ bannerView: GADBannerView) { // Pause your game or perform any necessary actions when the ad is clicked } // Tells the delegate that the full-screen view will be dismissed. func adViewWillDismissScreen(_ bannerView: GADBannerView) { // Resume your game or perform any necessary actions when the ad is dismissed } // Tells the delegate that the full-screen view has been dismissed. func adViewDidDismissScreen(_ bannerView: GADBannerView) { // Load a new banner ad when the previous one is dismissed bannerView.load(GADRequest()) } // Tells the delegate that the user click will open another app (such as the App Store), backgrounding the current app. func adViewWillLeaveApplication(_ bannerView: GADBannerView) { // Handle the user leaving the app, e.g., pause the game } // Tells the delegate that a click on an ad failed to open a full-screen view. func adView(_ bannerView: GADBannerView, didFailToPresentFullScreenContentWithError error: Error) { print("Ad did fail to present full screen content.") } func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { print("error mess: \(error)") } }
问题分析与修复步骤
1. 核心问题:缺少广告加载成功回调
你的代码仅处理了广告加载失败的场景,但从未将isBannerAdReady设为true——这是广告无法显示的关键原因。AdMob横幅广告加载成功时会触发adViewDidReceiveAd:方法,必须实现此方法来更新标记状态。
2. 重复回调方法冲突
代码中存在两个重复的广告加载失败回调:adView(_:didFailToReceiveAdWithError:)和bannerView(_:didFailToReceiveAdWithError:),会导致方法调用逻辑混乱,需保留其中一个统一实现。
3. 广告布局与尺寸优化
自定义尺寸适配性较差,建议使用官方预设的kGADAdSizeBanner;同时添加广告视图时需设置布局约束,避免广告被隐藏或位置异常。
修复后的关键代码修改
添加广告加载成功回调
func adViewDidReceiveAd(_ bannerView: GADBannerView) { print("Banner ad loaded successfully") isBannerAdReady = true // 可选:加载成功后直接显示,或在游戏合适时机调用showBannerAd() // showBannerAd() }
移除重复的失败回调
保留单一的失败处理方法:
func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { print("Failed to load banner ad: \(error.localizedDescription)") isBannerAdReady = false }
优化广告布局(可选)
在showBannerAd()中添加约束,确保广告固定在屏幕底部:
func showBannerAd() { guard isBannerAdReady, let view = self.view else { print("No ad ready to be displayed or view is nil.") return } bannerView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(bannerView) NSLayoutConstraint.activate([ bannerView.centerXAnchor.constraint(equalTo: view.centerXAnchor), bannerView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) isBannerAdReady = false }
使用官方推荐的广告尺寸
修改loadBannerAd()中的尺寸设置:
func loadBannerAd() { bannerView = GADBannerView(adSize: kGADAdSizeBanner) bannerView.adUnitID = "ca-app-pub-3940256099942544/2934735716" // 替换为你的广告单元ID bannerView.rootViewController = self.view?.window?.rootViewController bannerView.delegate = self bannerView.load(GADRequest()) }
额外注意事项
- 测试阶段务必使用AdMob提供的测试广告单元ID,避免触发平台限制;
- 确保调用
showBannerAd()的时机在广告加载成功之后,比如在adViewDidReceiveAd中直接调用,或在游戏关卡结束、菜单界面等合适节点触发。
内容的提问来源于stack exchange,提问作者Saland
相关产品推荐
相关产品推荐

