I have an implementation of GADInterstitial
class AdsManager {
let adsAppId = MY_ID
let fullScreenAdUnitId = MY_ID
static let manager: AdsManager = AdsManager()
private var interstitial: GADInterstitial!
private init () {
createAndLoadInterstitial()
}
func presentInterstitial(fromViewController viewController: UIViewController) {
if interstitial.isReady {
interstitial.present(fromRootViewController: viewController)
}
else {
print("Interstitial is not ready")
}
createAndLoadInterstitial()
}
private func createAndLoadInterstitial() {
//TODO: replace test ad unit id with production
interstitial = GADInterstitial(adUnitID: MY_ID)
interstitial.load(GADRequest())
}
}
and I show this ads like this:
func touchedButton(_ sender: UIButton) {
AdsManager.manager.presentInterstitial(fromViewController: self)
}
Everythink works and looks fine but when I was debugging I found something strange:
Four instances of the same view. Anyone know is it good? Or maybe I made a mistake in my AdsManager? Maybe Firebase implementation mistake?
The number of GADUIKitWebView's is dependent on the type of advertisement that is presented. A video, image, and text ad will all have different layouts. Based on the amount of memory being used I would assume it is correct.
View hierarchy of an interactive GADInterstitial advertisement:
Besides that, you do have a problem with your implementation. Your problem is in this function:
func presentInterstitial(fromViewController viewController: UIViewController) {
if interstitial.isReady {
interstitial.present(fromRootViewController: viewController)
}
else {
print("Interstitial is not ready")
}
createAndLoadInterstitial() // PROBLEM
}
You should move createAndLoadInterstitial() into the else so you only load another GADInterstitial when you actually need one. For example:
func presentInterstitial(fromViewController viewController: UIViewController) {
if interstitial.isReady {
interstitial.present(fromRootViewController: viewController)
}
else {
print("Interstitial is not ready")
createAndLoadInterstitial()
}
}
In addition to this you should implement the GADInterstitial delegate methods and load another GADInterstitial only after it has dismissed the screen. For example:
/// Called just after dismissing an interstitial and it has animated off the screen.
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
print("interstitialDidDismissScreen")
createAndLoadInterstitial()
}
Related
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 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
When my callButton is clicked it rings a phone number, I want to display my interstitial ad before the call is made. I have tested my ad on the "IBAction function ad" button and it works on the button but when I call it on the callButton func it will not work and goes straight to making a call.
class ProfilePageViewController: UIViewController, MFMessageComposeViewControllerDelegate, UITableViewDelegate, UIAlertViewDelegate, GADInterstitialDelegate {
#IBAction func ad(_ sender: Any) {
if self.interstitialAd.isReady {
self.interstitialAd.present(fromRootViewController: self)
}
}
#IBAction func callButton(_ sender: Any) {
if let contactopt = contact{
if let url = NSURL(string: "tel://\(contactopt)") {
// UIApplication.shared.openURL(url as URL)
UIApplication.shared.open(url as URL, options: [:], completionHandler: nil)
}
}
}
var interstitialAd: GADInterstitial!
func reloadInterstitialAd() -> GADInterstitial {
var interstitial = GADInterstitial(adUnitID: "ca-app-pub-/6966780536")
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
self.interstitialAd = reloadInterstitialAd()
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitialAd = reloadInterstitialAd()
}
override func viewDidLoad() {
self.interstitialAd = GADInterstitial(adUnitID: "ca-app-pub-/6966780536")
let request = GADRequest()
request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
self.interstitialAd.load(request)
self.interstitialAd = reloadInterstitialAd()
super.viewDidLoad()
}
}
Of course it goes to making a call. That's what you're telling it to do with UIApplication.shared.open.
Make the call once the ad has been dismissed in interstitialDidDismissScreen.
Also check to see if there is an ad to present, interstitialAd.isReady. If there is no ad to present go straight to making the call.
You're also doing the same thing twice in your viewDidLoad:
// Sets up an ad
self.interstitialAd = GADInterstitial(adUnitID: "ca-app-pub-/6966780536")
let request = GADRequest()
request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
self.interstitialAd.load(request)
// Creates a new ad
self.interstitialAd = reloadInterstitialAd()
Just call self.interstitialAd = reloadInterstitialAd().
I believe your problem has to do with the synchrony of the present method on the interstitial. I do not know what the implementation is, but it seems like the ad's presentation does not block the thread on which it was called. You should try implementing GADInterstitialDelegate to grab the event when the ad is presented then proceed to make your call from there.
Try this:
GADInterstitial is a one time use object. That means once an
interstitial is shown, hasBeenUsed returns true and the interstitial
can't be used to load another ad. To request another interstitial,
you'll need to create a new GADInterstitial object. The best practice,
as shown above, is to have a helper method to handle creating and
loading an interstitial.
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()
}
#IBAction func ad(_ sender: Any) {
if self.interstitialAd.isReady {
self.interstitialAd.present(fromRootViewController: self)
}
}
This question already exists:
admob interstitial alway returns false
Closed 6 years ago.
i have this game and i created 3 funcions in my gameviewcontroller and here they are
func getInterstitialAd(){
interstitial = GADInterstitial(adUnitID: "ca-app-pub-1782852253088296/5018877964")
let requestInterstitial = GADRequest()
interstitial.load(requestInterstitial)
}
func showAd() {
if (interstitial.isReady == true){
interstitial.present(fromRootViewController: GameViewController())
}else{
print("ad wasn't ready")
interstitial = createAd()
}
}
func createAd() -> GADInterstitial{
let interstital = GADInterstitial(adUnitID: "ca-app-pub-1782852253088296/5018877964")
interstitial.load(GADRequest())
return interstital
}
and in one of my scene called StartMenu , i call those function
var viewController: GameViewController!
and then i call the functions
viewController.getInterstitialAd()
viewController.showAd()
but it always returns ad not ready , and false for interstitial.isReady,
but also the getInterstitial function is always called .
can someone help with that please
Create a new swift file AdMobDelegate :-
import UIKit
import GoogleMobileAds
class AdMobDelegate: NSObject, GADInterstitialDelegate {
var interstitialView: GADInterstitial!
func createAd() -> GADInterstitial {
interstitialView = GADInterstitial(adUnitID: "Your Key")
interstitialView.delegate = self
let request = GADRequest()
interstitialView.loadRequest(request)
return interstitialView
}
func showAd() {
if interstitialView != nil {
if (interstitialView.isReady == true){
interstitialView.present(fromRootViewController:currentVc)
} else {
print("ad wasn't ready")
interstitialView = createAd()
}
} else {
print("ad wasn't ready")
interstitialView = createAd()
}
}
func interstitialDidReceiveAd(ad: GADInterstitial!) {
print("Ad Received")
if ad.isReady {
interstitialView.present(fromRootViewController: currentVc)
}
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
print("Did Dismiss Screen")
}
func interstitialWillDismissScreen(ad: GADInterstitial!) {
print("Will Dismiss Screen")
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
print("Will present screen")
}
func interstitialWillLeaveApplication(ad: GADInterstitial!) {
print("Will leave application")
}
func interstitialDidFailToPresentScreen(ad: GADInterstitial!) {
print("Failed to present screen")
}
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print("\(ad) did fail to receive ad with error \(error)")
}
}
Now you can use the object of this delegate class in other files as follows :-
//Define admobdelegate as global variable
var admobDelegate = AdMobDelegate()
//Declare a global variable currentVc to hold reference to current view controller
var currentVc: UIViewController!
class abc1: UIViewController {
override func viewdidload() {
super.viewdidload()
currentVc = self
admobDelegate.showAd()
}
override func viewDidAppear() {
super.viewDidAppear()
currentVc = self
}
}
class abc2: UIViewController {
override func viewdidload() {
super.viewdidload()
currentVc = self
admobDelegate.showAd()
}
override func viewDidAppear() {
super.viewDidAppear()
currentVc = self
}
}
Code is in Swift 2.2. Write your equivalent code in swift 3 in case of syntax error.
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.