Search code examples
swiftxcodeadmobinterstitial

How to run function multiple times in xcode?


I want to show my interstitial ad after the player have died. Meaning the interstitial ad will load in my game over scene. But i can't just write the function name in the viewdidload section. So is there a way for me to run my interstitialAd function when the player gets to the gameOverScene?

If there was an update function, i would just make a boolean value like so:

var interstitialAdShow = false

and then write this in my didmovetoview:

interstitalAdShow = true

and then in my update function:

If interstitailAdShow == true{
     interstitial.present(fromRootViewController: self)
}

But now when there is no update function in the GameViewController, and i can't do it inside of my gameOverScene.swift i can't use this solution, is there another way for me to trigger my interstitial ad function when the gameOverScene comes up.

BTW here is my codes

import UIKit
import SpriteKit
import StoreKit
import GameplayKit
import GoogleMobileAds


var reklameNummer = 0


class GameViewController: UIViewController, GADBannerViewDelegate, GADRewardBasedVideoAdDelegate {


    var rewardBaseAd: GADRewardBasedVideoAd!


    var interstitial: GADInterstitial!

    @IBOutlet weak var bannerView: GADBannerView!

    override func viewDidLoad() {





        super.viewDidLoad()

        let request2 = GADRequest()
        request2.testDevices = [kGADSimulatorID]
        bannerView.delegate = self
        bannerView.adUnitID = "ca-app-pub-1110799225910030/5762940412"
        bannerView.rootViewController = self
        //bannerView.load(request2)


        interstitial = GADInterstitial(adUnitID: "ca-app-pub-1110799225910030/7460037600")
        let request = GADRequest()
        interstitial.load(request)









        if let view = self.view as! SKView? {
            // Load the SKScene from 'GameScene.sks'
            if let scene = SKScene(fileNamed: "MenuScene") {
                runTheInterStitialAd()
                // Set the scale mode to scale to fit the window
                scene.scaleMode = .aspectFill

                // Present the scene
                view.presentScene(scene)



                rewardBaseAd = GADRewardBasedVideoAd.sharedInstance()
                rewardBaseAd.delegate = self
                //rewardBaseAd.load(GADRequest(), withAdUnitID: "ca-app-pub-1110799225910030/4904503594")

            }



            view.ignoresSiblingOrder = true

            view.showsFPS = false
            view.showsNodeCount = false
        }
    }

    override var shouldAutorotate: Bool {
        return true
    }

    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        if UIDevice.current.userInterfaceIdiom == .phone {
            return .allButUpsideDown
        } else {
            return .all
        }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Release any cached data, images, etc that aren't in use.

    }

    override var prefersStatusBarHidden: Bool {
        return true
    }



//MARK:     Video ad
    func rewardBasedVideoAd(_ rewardBasedVideoAd: GADRewardBasedVideoAd,
                            didRewardUserWith reward: GADAdReward) {

    }
    func rewardBasedVideoAdDidReceive(_ rewardBasedVideoAd:GADRewardBasedVideoAd) {
        //print.text?.append("Reward based video ad is received.\n")
    }
    func rewardBasedVideoAdDidOpen(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
        //print.text?.append("Opened reward based video ad.\n")
    }
    func rewardBasedVideoAdDidStartPlaying(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
        //print.text?.append("Reward based video ad started playing.\n")
    }
    func rewardBasedVideoAdDidClose(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
    }
    func rewardBasedVideoAdWillLeaveApplication(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
        //print.text?.append("Reward based video ad will leave application.\n")
    }
    func rewardBasedVideoAd(_ rewardBasedVideoAd: GADRewardBasedVideoAd,
                            didFailToLoadWithError error: Error) {
        //print.text?.append("Reward based video ad failed to load.\n")
    }





//MARK:     Interstitial ad
    func runTheInterStitialAd(){
        var runFunc = SKAction.run(showInterstitialAdInScene)
        var wait = SKAction.wait(forDuration: 1)
        var sequence = SKAction.sequence([wait, runFunc])
    }
    func showInterstitialAdInScene() {
        print("this code is working")
        if var scene = SKScene(fileNamed: "Gameoverscene") {

            //  TRUE
            if (interstitial.isReady) == true{
                interstitial.present(fromRootViewController: self)
                gameNumber = 0
            }




            //  FALSE
            if (interstitial.isReady) == false{
                interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/1033173712")
                let request = GADRequest()
                interstitial.load(request)
            }
        }
    }






    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if rewardBaseAd.isReady{
            if reklameNummer == 1{
                reklameNummer += 1
                //rewardBaseAd.present(fromRootViewController: self)
                //rewardBaseAd.load(GADRequest(), withAdUnitID: "ca-app-pub-1110799225910030/4904503594")
            }
        }
        if rewardBaseAd.isReady{
            if reklameNummer == 2{
                reklameNummer = 0
                //rewardBaseAd.present(fromRootViewController: self)
                //rewardBaseAd.load(GADRequest(), withAdUnitID: "ca-app-pub-1110799225910030/4904503594")
            }
        }



        if gameNumber == 2{
            //showInterstitialAdInScene()
        }

    }
}

Solution

  • One way to do this is use a callback, which is a way to send the class that created a new class(scene) to that new class(scene) as an argument. This way the new class(scene) can call functions from the old class. Beneath is how to implement this in your code. First I make a custom initialiser which takes in the creating class as an argument and assigns it to a local variable(myCreator). Then in the function called when a player dies(deathFunction()), I call the runIntersitialAd() function from the creating class. I also changed the code which sets up the MenuScene from the GameViewController to send itself(GameViewController class) as an argument inside the MenuScene initialisation.

    Change your scene class to something like this:

    class MenuScene {
        var myCreator : GameViewController!
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    
        convenience init(fileNamed: String, VCwhoCreatedMe: GameViewController) {
    
           self.init(fileNamed: fileNamed, VCwhoCreatedMe: VCwhoCreatedMe)
           myCreator = VCwhoCreatedMe
        } 
    
        ....your other code
    
        deathFunction() { //whatever code you use when the player dies
           myCreator.runTheInterStitialAd() //because of the callback construction this is now possible.
           ...other code
        }
    }
    

    Inside your GameViewController, function viewDidLoad():

    if let view = self.view as! SKView? {
    
       if let scene = MenuScene(fileNamed: "MenuScene",VCwhoCreatedMe: self ) {
           runTheInterStitialAd()
    
           scene.scaleMode = .aspectFill
    
    
           view.presentScene(scene)    
           ..... other code    
       }
    }