Swift Admob 插页式错误
Swift Admob Interstitial Error
这很长,但可能很容易解决。
大部分是代码,跳到底部会有一个 tl;dr
嘿,我已经学习了大约 10 个关于让 Admob 插页式广告在我的 Swift Spritekit 游戏中工作的教程。除了我见过的所有教程都使用带按钮的 IBAction。
目前我希望广告每隔一段时间在菜单上弹出一次。 (只是开始,我可能会稍后更改)。
这一切都很完美,但是一旦我按下播放按钮(转到不同的场景)然后 return 到菜单场景。 (GameScene) 插页功能不再发生。没有错误,只是在应用程序完全关闭并重新打开之前不再执行此操作。
这是代码。
在我的 GameViewController class 我有:
var interstital: GADInterstitial!
并且在 GameViewController 中加载我有:
if let scene = GameScene(fileNamed:"GameScene") {
let skView = self.view as? SKView
skView!.ignoresSiblingOrder = false
scene.scaleMode = .AspectFill
scene.viewController = self
skView!.presentScene(scene)
interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687746813194/9687097060")
let request = GADRequest()
interstital.loadRequest(request)
也在GameViewController中class我有这些功能:
func ShowAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
}
else{
print("The interstitial wasn't ready.")
}
}
func CreateAd() -> GADInterstitial {
let interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687748683194/9687247060")
interstital.loadRequest(GADRequest())
return interstital
}
在我的 GameScene 的(菜单)class 我有:
var viewController: GameViewController!
在我的 GameScene 中 class 我有显示插页式广告的功能。
func adThing(){
//viewController?.ShowAd()
print("starting the ad function")
let waitForInterstitial = SKAction.waitForDuration(15.0)
let waitForInterstitialShort = SKAction.waitForDuration(3.0)
let showInterstitialAd = SKAction.runBlock({self.viewController?.ShowAd(); print("the function has been called..")})
let waitThenShowInterstitial = SKAction.sequence([showInterstitialAd,waitForInterstitial])
let waitThenShowInterStitialForever = SKAction.repeatActionForever(waitThenShowInterstitial)
//self.runAction(waitThenShowInterStitialForever)
self.runAction(waitForInterstitialShort, completion: {
print("its waited 3 seconds and will now start the ad thingo")
self.runAction(waitThenShowInterStitialForever)
})
print("done")
}
所以,我每 20 秒在我的 GameScene 中调用 ShowAd 函数(位于 gameviewcontroller 中),(我已经确认它至少认为它正在调用该函数。 ) 当应用程序一开始就打开时,它可以完美运行。但是当我改变场景然后 return 到菜单场景 (GameScene) 时,我的 GameScene 函数中的 Prints 不断发生,我的代码 认为 它正在调用 ShowAd 函数, 但似乎什么都没有发生,没有弹出插页,甚至没有 GameViewController 中 ShowAd 函数中的打印。
所以好像在我改变场景和 return 之后,我的游戏忘记了 GameViewController 是什么。如果我在没有“?”的情况下引用 GameViewController它会使我的游戏崩溃并出现错误 "unexpectedly found nil while unwrapping an optional." 因此,在更改场景后,GameViewController 可能变为 nil?我该如何解决这个问题。
请帮帮我!!! (我是编程新手,以防你看不出来。我知道对我的代码做出冷嘲热讽的评论一定很诱人,它真的很简单,目前还不是那么好。)
非常感谢你能帮助我,哇..感谢阅读所有这些..;)
你的问题很可能是一旦你转换到一个新场景 viewController 属性 被设置为 nil 因此如果你使用 !.
会崩溃
一般来说,在您的 SKScenes 中引用 viewController 并不是最佳做法,您应该使用 Delegation 或 NSNotification Center。
1) 通知中心(最简单的方法)
在你的 ViewController 中你有展示广告的功能,在 ViewDidLoad
中添加一个 NSNotificationCenter 观察者
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showAd), name: "ShowInterAdKey", object: nil)
(Selector是要调用的函数,name是引用这个observer的key)
比起在您的 SKScenes 中显示广告,您只需 post 通知
NSNotificationCenter.defaultCenter().postNotificationName("ShowInterAdKey", object: nil)
2) 有关委托示例,请查看这些文章。
http://stephenradford.me/creating-a-delegate-in-swift/
https://www.natashatherobot.com/ios-weak-delegates-swift/
3) 我还注意到您在展示广告之前没有预加载广告,这不是很有效并且可能导致延迟展示广告。
你应该打电话给
interstital = CreateAd()
在 viewDidLoad 中,因此它会尽快加载第一个广告。比您应该使用 adMob 委托方法
func interstitialDidDismissScreen(ad: GADInterstitial!) {
// load next ad
interstital = CreateAd()
当前广告关闭后立即加载下一个广告。
要使用委托,您可以在 ViewController
中创建扩展
extension MyViewController: GADInterstitialDelegate {
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("AdMob interstitial did receive ad from: \(ad.adNetworkClassName)")
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial will present")
// pause game/app
}
func interstitialWillDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial about to be closed")
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial closed, reloading...")
interstitial = createAd()
}
func interstitialWillLeaveApplication(ad: GADInterstitial!) {
print("AdMob interstitial will leave application")
// pause game/app
}
func interstitialDidFailToPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial did fail to present")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
}
要确保调用这些函数,请转到您的 createAd 函数并在返回广告之前添加此行
let interstitial = ...
interstitial.delegate = self
最后,您的 showAd 方法应该如下所示
func showAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
} else{
print("The interstitial wasn't ready, reloading again.")
interstital = CreateAd()
}
}
4) 如果您正在寻找更可重用的解决方案,您还可以在 gitHub 上查看我的助手。
https://github.com/crashoverride777/Swift-AdMob-AppLovinTVOS-CustomAds-Helpers
作为一般提示,您还应遵循 swift 命名约定,您的函数和属性应以小写字母开头。只有 类、结构、枚举和协议应该以大写字母开头。
它使您的代码更难自己阅读和在 Whosebug 上阅读,因为它被标记为蓝色但不应该。你有时做有时不做。
希望对您有所帮助
我敢打赌这是你的问题:
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
您正在展示您的插页式广告,然后立即覆盖您的 interstitial
。您应该实施 GADInterstitial
的委托方法并在调用 func interstitialDidDismissScreen(ad: GADInterstitial!)
后调用您的 func CreateAd() -> GADInterstitial
。
如果您的设备由于以下原因不断崩溃:
interstitial.delegate = self
然后将其放入您的 CreatAndLoadInterstitial(),而不是您的 viewDidLoad()
这很长,但可能很容易解决。 大部分是代码,跳到底部会有一个 tl;dr
嘿,我已经学习了大约 10 个关于让 Admob 插页式广告在我的 Swift Spritekit 游戏中工作的教程。除了我见过的所有教程都使用带按钮的 IBAction。 目前我希望广告每隔一段时间在菜单上弹出一次。 (只是开始,我可能会稍后更改)。 这一切都很完美,但是一旦我按下播放按钮(转到不同的场景)然后 return 到菜单场景。 (GameScene) 插页功能不再发生。没有错误,只是在应用程序完全关闭并重新打开之前不再执行此操作。
这是代码。
在我的 GameViewController class 我有:
var interstital: GADInterstitial!
并且在 GameViewController 中加载我有:
if let scene = GameScene(fileNamed:"GameScene") {
let skView = self.view as? SKView
skView!.ignoresSiblingOrder = false
scene.scaleMode = .AspectFill
scene.viewController = self
skView!.presentScene(scene)
interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687746813194/9687097060")
let request = GADRequest()
interstital.loadRequest(request)
也在GameViewController中class我有这些功能:
func ShowAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
}
else{
print("The interstitial wasn't ready.")
}
}
func CreateAd() -> GADInterstitial {
let interstital = GADInterstitial(adUnitID: "ca-app-pub-9776687748683194/9687247060")
interstital.loadRequest(GADRequest())
return interstital
}
在我的 GameScene 的(菜单)class 我有:
var viewController: GameViewController!
在我的 GameScene 中 class 我有显示插页式广告的功能。
func adThing(){
//viewController?.ShowAd()
print("starting the ad function")
let waitForInterstitial = SKAction.waitForDuration(15.0)
let waitForInterstitialShort = SKAction.waitForDuration(3.0)
let showInterstitialAd = SKAction.runBlock({self.viewController?.ShowAd(); print("the function has been called..")})
let waitThenShowInterstitial = SKAction.sequence([showInterstitialAd,waitForInterstitial])
let waitThenShowInterStitialForever = SKAction.repeatActionForever(waitThenShowInterstitial)
//self.runAction(waitThenShowInterStitialForever)
self.runAction(waitForInterstitialShort, completion: {
print("its waited 3 seconds and will now start the ad thingo")
self.runAction(waitThenShowInterStitialForever)
})
print("done")
}
所以,我每 20 秒在我的 GameScene 中调用 ShowAd 函数(位于 gameviewcontroller 中),(我已经确认它至少认为它正在调用该函数。 ) 当应用程序一开始就打开时,它可以完美运行。但是当我改变场景然后 return 到菜单场景 (GameScene) 时,我的 GameScene 函数中的 Prints 不断发生,我的代码 认为 它正在调用 ShowAd 函数, 但似乎什么都没有发生,没有弹出插页,甚至没有 GameViewController 中 ShowAd 函数中的打印。
所以好像在我改变场景和 return 之后,我的游戏忘记了 GameViewController 是什么。如果我在没有“?”的情况下引用 GameViewController它会使我的游戏崩溃并出现错误 "unexpectedly found nil while unwrapping an optional." 因此,在更改场景后,GameViewController 可能变为 nil?我该如何解决这个问题。
请帮帮我!!! (我是编程新手,以防你看不出来。我知道对我的代码做出冷嘲热讽的评论一定很诱人,它真的很简单,目前还不是那么好。)
非常感谢你能帮助我,哇..感谢阅读所有这些..;)
你的问题很可能是一旦你转换到一个新场景 viewController 属性 被设置为 nil 因此如果你使用 !.
会崩溃一般来说,在您的 SKScenes 中引用 viewController 并不是最佳做法,您应该使用 Delegation 或 NSNotification Center。
1) 通知中心(最简单的方法)
在你的 ViewController 中你有展示广告的功能,在 ViewDidLoad
中添加一个 NSNotificationCenter 观察者 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showAd), name: "ShowInterAdKey", object: nil)
(Selector是要调用的函数,name是引用这个observer的key)
比起在您的 SKScenes 中显示广告,您只需 post 通知
NSNotificationCenter.defaultCenter().postNotificationName("ShowInterAdKey", object: nil)
2) 有关委托示例,请查看这些文章。
http://stephenradford.me/creating-a-delegate-in-swift/
https://www.natashatherobot.com/ios-weak-delegates-swift/
3) 我还注意到您在展示广告之前没有预加载广告,这不是很有效并且可能导致延迟展示广告。
你应该打电话给
interstital = CreateAd()
在 viewDidLoad 中,因此它会尽快加载第一个广告。比您应该使用 adMob 委托方法
func interstitialDidDismissScreen(ad: GADInterstitial!) {
// load next ad
interstital = CreateAd()
当前广告关闭后立即加载下一个广告。
要使用委托,您可以在 ViewController
中创建扩展 extension MyViewController: GADInterstitialDelegate {
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("AdMob interstitial did receive ad from: \(ad.adNetworkClassName)")
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial will present")
// pause game/app
}
func interstitialWillDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial about to be closed")
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("AdMob interstitial closed, reloading...")
interstitial = createAd()
}
func interstitialWillLeaveApplication(ad: GADInterstitial!) {
print("AdMob interstitial will leave application")
// pause game/app
}
func interstitialDidFailToPresentScreen(ad: GADInterstitial!) {
print("AdMob interstitial did fail to present")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
}
要确保调用这些函数,请转到您的 createAd 函数并在返回广告之前添加此行
let interstitial = ...
interstitial.delegate = self
最后,您的 showAd 方法应该如下所示
func showAd() {
print("doing the showadfunc now")
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
} else{
print("The interstitial wasn't ready, reloading again.")
interstital = CreateAd()
}
}
4) 如果您正在寻找更可重用的解决方案,您还可以在 gitHub 上查看我的助手。
https://github.com/crashoverride777/Swift-AdMob-AppLovinTVOS-CustomAds-Helpers
作为一般提示,您还应遵循 swift 命名约定,您的函数和属性应以小写字母开头。只有 类、结构、枚举和协议应该以大写字母开头。 它使您的代码更难自己阅读和在 Whosebug 上阅读,因为它被标记为蓝色但不应该。你有时做有时不做。
希望对您有所帮助
我敢打赌这是你的问题:
if (interstital.isReady) {
print("there is an inter ready")
interstital.presentFromRootViewController(self)
interstital = CreateAd()
您正在展示您的插页式广告,然后立即覆盖您的 interstitial
。您应该实施 GADInterstitial
的委托方法并在调用 func interstitialDidDismissScreen(ad: GADInterstitial!)
后调用您的 func CreateAd() -> GADInterstitial
。
如果您的设备由于以下原因不断崩溃:
interstitial.delegate = self
然后将其放入您的 CreatAndLoadInterstitial(),而不是您的 viewDidLoad()