Swift Admob Interstitial Error

三世轮回 提交于 2019-11-29 17:42:42

You problem most likely is that once you transition to a new scene the viewController property is set to nil hence a crash if you use !.

In general its not the best practice to reference the viewController in your SKScenes, you should use Delegation or NSNotification Center.

1) Notification Center (easiest way)

In your ViewController where you have the function to show ads add a NSNotificationCenter observer in ViewDidLoad

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

(Selector is the function to call and name is the key to reference this observer)

Than in your SKScenes when you want to show the ad you simply post the notification

 NSNotificationCenter.defaultCenter().postNotificationName("ShowInterAdKey", object: nil)

2) For delegation examples check out these articles.

http://stephenradford.me/creating-a-delegate-in-swift/

https://www.natashatherobot.com/ios-weak-delegates-swift/

3) I also noticed that you are not preloading the ads before you show them, which is not very efficient and can cause delays showing ads.

You should call

  interstital = CreateAd()

in viewDidLoad so it will load the first ad ASAP. Than you should use the adMob delegate method

 func interstitialDidDismissScreen(ad: GADInterstitial!) {
     // load next ad
     interstital = CreateAd()

to immediately load the next ad once the current one is closed.

To use the delegates you can create an extension in 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)
   }
}

To make sure these get called go to your createAd function and add this line before returning the ad

 let interstitial = ...
 interstitial.delegate = self

Finally your showAd method should look like this

  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) You can also check out my helper on gitHub if you are looking for a more reusable solution.

https://github.com/crashoverride777/Swift-AdMob-AppLovinTVOS-CustomAds-Helpers

As a general tip you should also follow the swift naming conventions, your func and properties should start with small letters. Only classes, structs, enums and protocols should start with capital letters. It makes your code harder to read for yourself and on stackoverflow because it is marked blue but shouldn't. You are sometimes doing and sometimes not.

Hope this helps

I'd bet this is your issue:

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

You're presenting your interstitial and then immediately overwriting your interstitial. You should be implementing the GADInterstitial's delegate methods and calling your func CreateAd() -> GADInterstitial once func interstitialDidDismissScreen(ad: GADInterstitial!) is called.

if your device keeps crashing because of:

interstitial.delegate = self

then put it in your CreatAndLoadInterstitial(), not your viewDidLoad()

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!