Swift Admob插页式错误

问题描述 投票:0回答:3

这很长,但它可能是一个非常简单的解决方案。大多数是代码,只是跳到底部,然后会有一个tl;博士

嘿,所以我遵循了大约10个关于让Admob插页式广告在我的Swift Spritekit游戏中工作的教程。除了我见过的所有教程,使用带按钮的IBAction。目前我希望广告在菜单上偶尔弹出一次。 (刚开始,我可能会在以后更改)。这一切都很完美,但是一旦我点击播放按钮(转到不同的场景),然后返回到菜单场景。 (GameScene)不再发生插页式功能。没有错误,只是在应用程序完全关闭并重新打开之前不再执行此操作。

这是代码。

在我的GameViewController类中,我有:

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类中我有以下功能:

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(菜单)课程中,我有:

var viewController: GameViewController!

在我的GameScene课程中,我有这个功能来显示插页式广告。

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中),(我已经确认它至少认为它正在调用该函数。)当应用程序打开时,它可以正常工作。但是当我改变场景然后返回菜单场景(GameScene)时,我的GameScene函数中的Prints继续发生,我的代码认为它正在调用ShowAd函数,但似乎没有发生任何事情,没有插入插页式广告,甚至不是GameViewController中ShowAd函数中的打印件。

所以看起来在我改变场景并返回之后,我的游戏忘记了GameViewController是什么。如果我在没有'?'的情况下引用GameViewController它将使我的游戏崩溃,错误是“在解开可选项时意外发现了nil”。所以改变场景后,GameViewController可能变成零吗?我怎样才能解决这个问题。

请帮我!!! (我不熟悉编程,以防你无法分辨。我知道对我的代码进行讽刺评论一定很诱人,它实在是很简单,而且目前还不是很好。)

非常感谢你,如果你可以帮助我,哇...感谢阅读所有这些..;)

ios swift null admob interstitial
3个回答
1
投票

您最有可能的问题是,一旦转换到新场景,viewController属性将设置为nil,因此如果您使用!则会崩溃!

通常,它不是在SKScenes中引用viewController的最佳实践,您应该使用Delegation或NSNotification Center。

1)通知中心(最简单的方法)

在具有显示广告功能的ViewController中,在ViewDidLoad中添加NSNotificationCenter观察器

 NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(showAd), name: "ShowInterAdKey", object: nil)

(选择器是调用函数,name是引用此观察者的关键)

在您希望展示广告时,只需在SKScenes中发布通知即可

 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

作为一般提示,您还应遵循快速命名约定,您的func和属性应以小写字母开头。只有类,结构,枚举和协议应以大写字母开头。它使您的代码更难以自己和stackoverflow读取,因为它标记为蓝色但不应该。你有时做,有时不做。

希望这可以帮助


1
投票

我敢打赌这是你的问题:

if (interstital.isReady) {
    print("there is an inter ready")
    interstital.presentFromRootViewController(self)
    interstital = CreateAd()

您正在展示您的插页式广告,然后立即覆盖您的interstitial。你应该实现GADInterstitial的委托方法,并在调用func CreateAd() -> GADInterstitial后调用你的func interstitialDidDismissScreen(ad: GADInterstitial!)


0
投票

如果您的设备因以下原因而一直崩溃:

interstitial.delegate = self

然后把它放在你的CreatAndLoadInterstitial()中,而不是你的viewDidLoad()

© www.soinside.com 2019 - 2024. All rights reserved.