I want to show an Interstitial Ad in the GameOverScene which is a SKScene that is shown through the main ViewController. With the code shown below the ad prints (“Ad Wasn’t Ready”) how do I fix this to work properly in the Game Over SKScene?
import GoogleMobileAds
import SpriteKit
import GameplayKit
import SwiftUI
class GameOverScene: SKScene {
var interstitial: GADInterstitial!
override func didMove(to view: SKView) {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
let request = GADRequest()
interstitial.load(request)
if interstitial.isReady {
interstitial.present(GameViewController())
} else {
print("Ad wasn't ready")
}
}
}
You're presenting ad before the load is completed. You need to show in delegate callback once the Ad is loaded successfully.
override func viewDidLoad() {
super.viewDidLoad()
interstitial = createAndLoadInterstitial()
}
func createAndLoadInterstitial() -> GADInterstitial {
var interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
}
Show the ad in load success callback.
/// Tells the delegate an ad request succeeded.
func interstitialDidReceiveAd(_ ad: GADInterstitial) {
print("interstitialDidReceiveAd")
if ad.isReady {
ad.present(fromRootViewController:self)
} else {
print("Ad wasn't ready")
}
}
You can find more details here, https://developers.google.com/admob/ios/interstitial
Related
I try to setup interstitial ads in my app. If I use a test unit ID, ad shows fine, but if I try to use the real unit ID, I see the error "Ad wasn't ready". What I do wrong? Thank for any help!
My code:
import UIKit
import GoogleMobileAds
class ViewController: UIViewController {
var interstitial: GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
interstitial = createAndLoadInterstitial()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
if self.interstitial.isReady {
self.interstitial.present(fromRootViewController: self)
} else {
print("Ad wasn't ready")
}
}
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "AdMob Real Unit ID")
interstitial.delegate = self
let request = GADRequest()
GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = ["my device ID from console"]
interstitial.load(request)
return interstitial
}
}
extension ViewController: GADInterstitialDelegate {
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
}
}
Console:
Launching interstitial ad immediately after page load is disallowed.
Refer Disallowed Interstitial implementation policy https://support.google.com/admob/answer/6201362?hl=en
A common issue is that even though you may intend for the ad to load
in between page content, the ad itself appears shortly after a new
page of content has loaded due to carrier latency. To prevent this
from happening, we recommend you pre-load the interstitial in advance.
To learn more about how to pre-load your interstitial ad, please
follow the AdMob Interstitial Ad developer guidelines for apps
developed for Android and iOS.
Only load the ad on viewDidLoad () https://developers.google.com/admob/ios/interstitial
class ViewController: UIViewController {
var interstitial: GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
let request = GADRequest()
interstitial.load(request)
}
}
and then Interstitials should be displayed during natural pauses in the flow of an app. Between levels of a game is a good example, or after the user completes a task.
#IBAction func doSomething(_ sender: AnyObject) {
...
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
} else {
print("Ad wasn't ready")
}
}
Solved:
To display your ad units, your AdMob account must be verified.
You must see message in the Google AdMob Console:
Your account is approved
Congratulations! We've verified your account information and your ad serving is enabled.
So, I had the interstitial ads working fine by following the code on the Admob website and then recently I updated my pods and with it the GoogleAdMob SDK.
Now when my interstitial Ad should present, nothing happens and in the console I have this error:
<GoogleThe provided view controller is not being presented.
[ProcessSuspension] 0x110adfbd0 - ProcessAssertion::processAssertionWasInvalidated()
Here is my code:
extension FirstViewController: GADInterstitialDelegate {
func showInterstitialAd() {
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
} else {
print("Ad wasn't ready")
}
}
func createAndLoadInterstitial() -> GADInterstitial {
var interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
}
}
In viewDidLoad I call:
func setUpInterstitial() {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
interstitial.delegate = self
let request = GADRequest()
interstitial.load(request)
}
and in ViewWillAppear
if InterstitialAd.counter >= 3 { self.showInterstitialAd(); InterstitialAd.counter = 0}
The intended logic is every 3 times a user views a page, namely FirstViewController, an interstitial ad shows.
Thank you in advance :)
You can update your code like below:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if InterstitialAd.counter >= 3 {
self.showInterstitialAd();
InterstitialAd.counter = 0
}
}
Remove your code from viewWillAppear.
I implemented a test adMob with Firebase:
override func viewDidLoad() {
super.viewDidLoad()
interstitial = createAndLoadInterstitial()
interstitial.delegate = self
....}
func createAndLoadInterstitial() -> GADInterstitial {
var interstitial = GADInterstitial(adUnitID: "testVideo")
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialWillDismissScreen(_ ad: GADInterstitial) {
print("interstitialWillDismissScreen")
UserDefaults.standard.set(false, forKey: "adWasShowing")
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
if ... {
...
}
interstitial = createAndLoadInterstitial()
print("interstitialDidDismissScreen")
}
The problem is when I get an ad (5sec video) and take the app to background and then to foreground again
interstitialWillDismissScreen and interstitialDidDismissScreen
automatically gets called resulting in closing the ad. I think many users will use this exploit to not stay on the video. Any idea on how to solve this?
I tried to set up a bool in UserDefaults in the "interstitialWillPresentScreen" and check it at "applicationWillEnterForeground", but I don't like this idea and also the interstitial request is not yet loaded (interstitialRequest must be recreated for every ad).
I am using Admob interstitials in my swift project and I am having trouble reloading the ads. The first interstitial displays fine, and when interstitialWillDismissScreen is called, it exits back to the game and reloads a new interstitial as it's supposed to. However, neither interstitialDidReceiveAd nor interstitialWillDismissScreen are called again, so after the second ad is displayed, no other ads come through. What am I missing?
import GoogleMobileAds
let appDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
class GameScene: SKScene, GKGameCenterControllerDelegate, GADInterstitialDelegate {
var interstitial: GADInterstitial!
override func didMoveToView(view: SKView) {
//preload interstitial ad
if NSUserDefaults.standardUserDefaults().boolForKey("paidToRemoveAds") == false {
interstitial = loadAd()
}
interstitial.delegate = self
}
func gameOver() {
runGoogleAd()
}
func loadAd() -> GADInterstitial {
let ad = GADInterstitial(adUnitID: "ca-app-pub-2963481692578498/7292484569")
let request = GADRequest()
request.testDevices = [kGADSimulatorID]
ad.loadRequest(request)
return ad
}
func runGoogleAd() {
if interstitial.isReady {
interstitial.presentFromRootViewController((appDelegate.window?.rootViewController)!)
}
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("ad loaded")
}
func interstitialWillDismissScreen(ad: GADInterstitial!) {
interstitial = loadAd()
print("loading new ad")
}
}
I assume loadAd() creates a new instance? You need to set the delegate on the new instance:
func interstitialWillDismissScreen(ad: GADInterstitial!) {
interstitial = loadAd()
interstitial.delegate = self // <-- You forgot this.
print("loading new ad")
}
Actually you should probably set the delegate in loadAd() since it is an instance member of this class.
I'm developing an iOS application using Swift2 and Xcode7. I'm trying to implement AdMob but it doesn't display my interstitial ad.
override func viewDidLoad() {
super.viewDidLoad()
_interstitial = createAndLoadInterstitial()
}
func createAndLoadInterstitial()->GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "interstitial_ID")
let gadRequest:GADRequest = GADRequest()
gadRequest.testDevices = ["test device id"]
interstitial.delegate = self
interstitial?.loadRequest(gadRequest)
return interstitial!
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
_interstitial?.presentFromRootViewController(self)
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
_interstitial = createAndLoadInterstitial()
}
I receive this error:
Request Error: No ad to show.
Request Error: No ad to show.
means that your request was successful but that Admob has no ad to show for your device at this time. The best way to ensure that you always have ads to show is to use mediation so that an unfulfilled request falls through to another ad network. Admob provides good mechanisms to do that.
You should have two Ad Unit ID's. One for your GADBannerView and one for your GADInterstitial. Make sure your Ad Unit ID supplied by AdMob for your interstitial is exactly the same as what they've given you. Update to the latest AdMob SDK, currently 7.5.0. Also consider calling presentFromRootViewController(self) at specific intervals or once the user completes a desired action. The way you have it setup now will keep presenting interstitials one after another because you are sending requests for new interstitials every time one is dismissed and then displaying the interstitial as soon as it receives an ad.
import UIKit
import GoogleMobileAds
class ViewController: UIViewController, GADInterstitialDelegate {
var myInterstitial : GADInterstitial?
override func viewDidLoad() {
super.viewDidLoad()
myInterstitial = createAndLoadInterstitial()
}
func createAndLoadInterstitial()->GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "Your Ad Unit ID")
interstitial.delegate = self
interstitial?.loadRequest(GADRequest())
return interstitial
}
#IBAction func someButton(sender: AnyObject) {
myInterstitial?.presentFromRootViewController(self)
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("interstitialDidReceiveAd")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print(error.localizedDescription)
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("interstitialDidDismissScreen")
myInterstitial = createAndLoadInterstitial()
}