在游戏场景中呈现插页式广告链接到GameViewController?

时间:2017-01-31 12:45:22

标签: ios swift admob scene interstitial

我已将横幅视图集成到我的应用程序中的场景中,但是我没有在其他场景中集成插页式广告。 这是我的代码: 导入SpriteKit 导入GameKit 导入GoogleMobileAds

 class GameOverMenu: SKScene, GKGameCenterControllerDelegate,    UIAlertViewDelegate {

var viewController: GameViewController!
var interstitial: GADInterstitial!

var myTimer = Timer()


override func didMove(to view: SKView) {

 createAndLoadInterstitial()

startMyTimer()




}


func createAndLoadInterstitial() {
interstitial = GADInterstitial(adUnitID: "...")
let request = GADRequest()
request.testDevices = [ kGADSimulatorID, "..." ]
interstitial.load(request)
}


func startMyTimer() {
myTimer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(GameOverMenu.myFunction), userInfo: nil, repeats: false)

}

func myFunction(){

if interstitial.isReady {
    interstitial.present(fromRootViewController: viewController)
} else {
    print("Ad wasn't ready")
}

 }

当尝试加载“致命错误:在展开可选值时意外发现nil”时失败。问题在于下面,好像代码是这样显示的,并且我在应用程序启动时加载GameOver场景它工作正常。我该如何解决这个问题?

if let view = self.view as! SKView? {




    // Load the SKScene from 'MainMenu.sks'
    if let scene = MainMenuScene(fileNamed: "MainMenu") {

        scene.viewController = self

        // Set the scale mode to scale to fit the window
        scene.scaleMode = .aspectFill

        // Present the scene
        view.presentScene(scene)


    }

    if let scene3 = GameOverMenu(fileNamed: "GameOver") {

        scene3.viewController = self

        // Set the scale mode to scale to fit the window
        scene3.scaleMode = .aspectFill

        view.presentScene(scene3)





    }

1 个答案:

答案 0 :(得分:0)

问题是当你在两个场景之间转换时,你会失去对GameViewController的引用,例如

 scene3.viewController = self

这就是为什么它只在您启动应用程序时才有效。

您也在使用!在那些属性

 var viewController: GameViewController!
 var interstitial: GADInterstitial!

所以,如果他们没有,你就会崩溃。所以你应该总是使用?当你不是100%确定那里有什么东西时。

 var viewController: GameViewController?
 var interstitial: GADInterstitial?

并且在您的代码中,例如“myFunction”,您将使用“?”当属性为零时,“if let”不会崩溃。

  if let ad = interstitial, let vc = viewController, ad.isReady {
       ad.present(fromRootViewController: vc)
   } else {
       print("Ad wasn't ready")
   }

您的问题的一般解决方法是您应该将所有AdMob代码直接移动到GameViewController中。您可以使用NotificationCenter或委派等内容将消息从场景转发到ViewController以显示广告。它并不是在SKScenes中引用ViewController的最佳实践。

因此,将所有广告代码移至ViewController,而不是在类实现之外的GameViewController中为通知密钥创建此扩展

 extension Notification.Name {
       static let showAd = Notification.Name(rawValue: "NotificationShowAd")
 } 

  class GameViewController: UIViewController {...

在ViewDidLoad中的GameViewController中,您可以添加观察者

override func viewDidLoad() {
    super.viewDidLoad()

         createAndLoadInterstitial()

         NotificationCenter.default.addObserver(self, selector: #selector(myFunction), name: .showAd, object: nil)

         ....
 }

现在,只要您需要在任何SKScenes中展示广告,就可以调用此

NotificationCenter.default.post(name: .showAd, object: nil)

为了让您的生活更轻松,请查看我在GitHub上的助手

https://github.com/crashoverride777/SwiftyAds

希望这会有所帮助