Interstitial iAds in SpriteKit?

☆樱花仙子☆ 提交于 2020-01-06 19:28:54

问题


I'm using SpriteKit for my iOS app, and need some full-screen (or sometimes called "interstitial" iAds to pop up every so often. I can figure out the code for when it happens, but I need to know how to add iAds without necessarily changing the View Controller.

I tried a [tutorial][1] by Techotopia on Interstitial iAds, but to do it I need to transition between actual View Controllers. Well, I tried this, but whenever transitioning back from the iAd view controller to the GameViewController, it messed it all up. The code in the GameViewController.m says that it is initially set to the main menu of my game (an SKScene). So when I try transitioning back from the iAd, instead of keeping the same SKScene up, it goes strait to my main menu scene.

I need these answers:

  1. Is there some way other than using two View Controllers to show Interstitial iAds?
  2. If not, how can I get around this problem?
  3. Would this problem also occur if I were to change my "Interstitial iAds" to "Pre-roll Video iAds?"

-

EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT! EDIT!

-

I ended up deciding to use crashoverride777's answer, and creating an Objective-C bridging header to convert his Swift code to Objective-C. But when referencing the Ads.swift's variable presentingViewController, it ends up being nil. Here is my code in GameViewController.m:

// Set up interstitial iAds.
Ads *adsClass = [[Ads alloc] init];
Ads *adsInstance = [Ads sharedInstance];
adsInstance.presentingViewController = self;

This, however, doesn't do anything. The function showInterAd gets called from my GameScene.m like it's supposed to, but no ad appears. In my Ads.swift, I added a log to see if presentingViewController is indeed nil.

print("iAd inter showing")
if (self.presentingViewController != nil) {
    print("presentingViewController != nil")
    iAdInterAdView.frame = presentingViewController.view.bounds
    presentingViewController.view.addSubview(iAdInterAdView)
    iAdInterAd!.presentInView(iAdInterAdView)
    UIViewController.prepareInterstitialAds()
    iAdInterAdView.addSubview(iAdInterAdCloseButton)
} else {
    print("presentingViewController == nil")
}

The log comes out like this every time: "presentingViewController == nil". I'm not sure what's going wrong, here.


回答1:


You can make use of my helper I posted on github. Its was made specifically for spritekit and you can call ads from anywhere without delegates etc or changing view controllers.

https://github.com/crashoverride777/Swift-2-iAds-and-AdMob-Helper

I think having a look at that helper should give you a good idea of where to start. Here is a cut down example of how it could look just for iAds Inter ads.

This is in swift so I am not sure if it is still helpful for you.

import iAd

class Ads: NSObject {

// MARK: - Static Properties

/// Shared instance
static let sharedInstance = Ads()

// MARK: - Properties

/// Presenting view controller
var presentingViewController: UIViewController!

/// iAd inter ad
private var iAdInterAd: ADInterstitialAd?

/// iAd inter ad view
private var iAdInterAdView = UIView()

/// iAd inter ad close button
private var iAdInterAdCloseButton = UIButton(type: UIButtonType.System)

// MARK: - Init
private override init() {
    super.init()
    print("Ads helper init")

   iAdInterAd = iAdLoadInterAd()
}

// MARK: - User Methods

/// Show inter ad
func showInterAd() {
    iAdShowInterAd()
}

/// Show inter ad randomly (33% chance)
func showInterAdRandomly() {
    let randomInterAd = Int(arc4random() % 3)
    print("randomInterAd = \(randomInterAd)")
    if randomInterAd == 1 {
        iAdShowInterAd()
    }
}

/// Remove all ads
func removeAllAds() {
    print("Removed all ads")

    if iAdInterAd != nil {
        iAdInterAd!.delegate = nil
        iAdInterAdCloseButton.removeFromSuperview()
        iAdInterAdView.removeFromSuperview()
    }
}

// MARK: - Internal Methods

/// iAd load inter ad
private func iAdLoadInterAd() -> ADInterstitialAd {
    print("iAd inter ad loading...")
    let iAdInterAd = ADInterstitialAd()
    iAdInterAd.delegate = self

    if UIDevice.currentDevice().userInterfaceIdiom == .Pad {
        iAdInterAdCloseButton.frame = CGRectMake(18, 18, 27, 27)
    } else {
        iAdInterAdCloseButton.frame = CGRectMake(13, 13, 22, 22)
    }

    iAdInterAdCloseButton.layer.cornerRadius = 11
    iAdInterAdCloseButton.setTitle("X", forState: .Normal)
    iAdInterAdCloseButton.setTitleColor(UIColor.grayColor(), forState: .Normal)
    iAdInterAdCloseButton.backgroundColor = UIColor.whiteColor()
    iAdInterAdCloseButton.layer.borderColor = UIColor.grayColor().CGColor
    iAdInterAdCloseButton.layer.borderWidth = 2
    iAdInterAdCloseButton.addTarget(self, action: "iAdPressedInterAdCloseButton:", forControlEvents: UIControlEvents.TouchDown)

    return iAdInterAd
}

/// iAd show inter ad
private func iAdShowInterAd() {
    guard iAdInterAd != nil else {
        print("iAd inter is nil, reloading")
        iAdInterAd = iAdLoadInterAd()
        return
    }

    if iAdInterAd!.loaded {
        print("iAd inter showing")
        iAdInterAdView.frame = presentingViewController.view.bounds
        presentingViewController.view.addSubview(iAdInterAdView)
        iAdInterAd!.presentInView(iAdInterAdView)
        UIViewController.prepareInterstitialAds()
        iAdInterAdView.addSubview(iAdInterAdCloseButton)

        //pauseTasks() // not really needed for inter as you tend to show them when not playing.
    } else {
        print("iAd inter not ready, reloading again...")
        iAdInterAd = iAdLoadInterAd()

    }
}

/// iAd inter ad pressed close button
func iAdPressedInterAdCloseButton(sender: UIButton) { // dont make private as its called with a selector
    print("iAd inter closed")
    iAdInterAd!.delegate = nil
    iAdInterAdCloseButton.removeFromSuperview()
    iAdInterAdView.removeFromSuperview()
    iAdInterAd = iAdLoadInterAd()

    //resumeTasks() // not really needed for inter as you tend to not show them during gameplay
}

/// Pause tasks in the app/game
private func pauseTasks() {
    // Pause app/game, music etc here.
    // you could use NSNotifactionCenter or Delegates to call methods in other SKScenes / ViewControllers
}

/// Resume tasks in the app/game
private func resumeTasks() {
    // Resume app/game, music etc here.
    // you could use NSNotifactionCenter or Delegates to call methods in other SKScenes / ViewControllers
     }
}

// MARK: - Delegates iAd Inter
extension Ads: ADInterstitialAdDelegate {

func interstitialAdDidLoad(interstitialAd: ADInterstitialAd!) {
    print("iAd inter did load")
}

func interstitialAdDidUnload(interstitialAd: ADInterstitialAd!) {
    print("iAd inter did unload")
}

func interstitialAd(interstitialAd: ADInterstitialAd!, didFailWithError error: NSError!) {
    print("iAd inter error \(error)")
    iAdInterAd!.delegate = nil
    iAdInterAdCloseButton.removeFromSuperview()
    iAdInterAdView.removeFromSuperview()
   }
}

Now you simply call

Ads.sharedInstance.presentingViewController = self 

in your GameViewController before doing anything else. This will init the helper and preload the first inter ad.

Than you simply call these anywhere you would like inter ads to show

GameData.sharedInstance.showInterAd()

or

GameData.sharedInstance.showInterAdRandomly() // 33% chance for ad



回答2:


Presenting interstitial in sprite kit is almost identical to in other parts of the app. The only difference is you present the add by calling all the iAd methods with 'self.view'. This gets the view the SKScene is presented in and present the iAd over it

also this can be used to present interstitial without switching view controllers

currentView.requestInterstitialAdPresentation()

to request from in the scene:

self.view?.requestInterstitialAdPresentation()

Notice how in the function call it says request. That is why it only shows up sometimes. When you 'request' an ad the device sends a request to apple asking for an ad. If you get a response back in a reasonable amount of time then the ad will present. If you do not get a response back in a reasonable amount of time (most likely due to poor internet) there the ad won't present because theres nothing to present. However if you request once and it doesn't present, the next time you ask it will definitely present because you already have an ad loaded from the last time you requested but it never got presented.



来源:https://stackoverflow.com/questions/33766047/interstitial-iads-in-spritekit

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