I've recently uploaded my application to App Store but I've found an error. My program crashes every time an interstitial (AdMob) begins and I've no idea why. It never crashes when I run the program from Xcode..
import GoogleMobileAds
First I've imported this one of course.
Also added this to my class
GADInterstitialDelegate
Inside the viewDidLoad() I've added this one:
interstitial = GADInterstitial(adUnitID: "AD-UNIT-ID")
let request = GADRequest()
request.testDevices = [ kGADSimulatorID] //Should this be removed now when the app is on App Store?
interstitial.load(request)
interstitial.delegate = self
Further down I've added this code to my save-button:
//Advertisement test
if self.interstitial.isReady
{
self.interstitial.present(fromRootViewController: self)
}
else
{
print("Advertisement is not ready!")
self.performSegue(withIdentifier: "History", sender: self)
}
And for the last I've this:
//Advertisement will dismiss from the screen
func interstitialDidDismissScreen(_ ad: GADInterstitial)
{
self.performSegue(withIdentifier: "History", sender: self)
}
How can I fix this problem? It crashes every time I press on that "Save button" and the screen is turning black and then boom, crashes.
So it never crashed before when I ran it from my Xcode project, but when I was in TestFlight and in App Store it crashes every time!
Related
I have integrated the google AdMob interstitial ads in my iOS App using the following code:-
import GoogleMobileAds
class ViewController: UIViewController, GADInterstitialDelegate {
var interstitial: GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
interstitial = GADInterstitial(adUnitID: "")
interstitial.delegate = self
let request = GADRequest()
interstitial.load(request)
}
// Google Ads
func interstitialDidReceiveAd(_ ad: GADInterstitial) {
interstitial.present(fromRootViewController: self)
}
}
When I run test ads, I am able to see the interstitial ads! But, after replacing the test ID with my Interstitial Ad Unit ID, I cannot see the live interstitial ads on my iOS app. Could anyone please help me to resolve this issue? Thanks:)
These are the logs after running my app on my iOS Device:-
You must test your google ads with test id like below as per google documentation.
Interstitial Test id
ca-app-pub-3940256099942544/4411468910
Adding test id and try again.
I'd like to display AdMob interstitials in my app. I manage to display test ads. As far as I understand to display test ads you should add test devices, so this is what I do. When I remove the test devices though, I don't get the real ads. I'd like to test somehow that real ads will be displayed. When I remove the test devices I get interstitial(_ ad: GADInterstitial, didFailToReceiveAdWithError error: GADRequestError) delegate method called and the error is: Request Error: No ad to show. This is my code based on the instructions here:
class MoviesViewController: UIViewController {
var interstitial: GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
interstitial = createAndLoadInterstitial()
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "<Ad-Unit-ID>")
interstitial.delegate = self
let request = GADRequest()
//request.testDevices = ["<Device-Test-ID>"]
interstitial.load(request)
return interstitial
}
#IBAction func didTapStartOver(_ sender: Any) {
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
} else {
print("Ad wasn't ready")
interstitial = createAndLoadInterstitial()
}
}
GADInterstitialDelegate:
extension MoviesViewController : GADInterstitialDelegate {
/// Tells the delegate an ad request succeeded.
func interstitialDidReceiveAd(_ ad: GADInterstitial) {
print("interstitialDidReceiveAd")
}
/// Tells the delegate an ad request failed.
func interstitial(_ ad: GADInterstitial, didFailToReceiveAdWithError error: GADRequestError) {
print("interstitial:didFailToReceiveAdWithError: \(error.localizedDescription)")
}
/// Tells the delegate that an interstitial will be presented.
func interstitialWillPresentScreen(_ ad: GADInterstitial) {
print("interstitialWillPresentScreen")
}
/// Tells the delegate the interstitial is to be animated off the screen.
func interstitialWillDismissScreen(_ ad: GADInterstitial) {
dismiss(animated: false, completion: nil)
print("interstitialWillDismissScreen")
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
print("interstitialDidDismissScreen")
interstitial = createAndLoadInterstitial()
}
/// Tells the delegate that a user click will open another app
/// (such as the App Store), backgrounding the current app.
func interstitialWillLeaveApplication(_ ad: GADInterstitial) {
print("interstitialWillLeaveApplication")
}
}
I added a mediation group and was able to receive one real ad. After that the issue persists (no more ads to show).
Changing the device for testing from iPad to iPhone also seems to help - the issue seems to be reproducible only on iPad.
I never used the test device feature. I always just plugged in the provided test ad id that is mentioned in their guides. When ready to test real ads, just switch to the live ad id they provide when you create the ad. Then it's good to go without changing any other code.
This question has been asked and answered multiple times here. And i've read them all, implemented all suggestions, and still it does not work. I'm currently doing it with a NotificationObserver and the ad is created, however it always returns false for isReady. Please let me know if anything sticks out.
GameViewController
var interstitial: GADInterstitial!
In viewDidLoad
interstitial = createAndLoadInterstitial()
NotificationCenter.default.addObserver(self, selector: #selector(self.showInterstitial), name:NSNotification.Name(rawValue: "showInterAd"), object: nil);
Ad functions
func showInterstitial(){
if (interstitial!.isReady) {
self.interstitial.present(fromRootViewController: self)
}else{
print("ad not ready?")
}
}
func createAndLoadInterstitial() -> GADInterstitial {
print("making ad")
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-6956068899232786/9340371153")
interstitial.delegate = self
let request = GADRequest()
request.testDevices = [kGADSimulatorID]
interstitial.load(request)
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
}
GameScene.swift
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "showInterAd"), object: nil)
All functions get called at correct times, but the ad just never becomes ready. I have triple checked the adUnitID, and tried on multiple devices/simulators.
So i've got it working. I do not know why this worked, and i'm assuming it has nothing to do with the app itself, but a bug or something within AdMob.
The fix was to replace the ad_unit_id with a different one from one of my other apps, which then made the ad become ready and display. I was then able to replace the ad_unit_id back to the correct one for this app and it still works.
It's like it needed one that had been used before to jumpstart it in to working. It's got me baffled, but hopefully this helps someone else.
I have this code:
func createAndLoadInterstitial() {
interstitial = GADInterstitial(adUnitID: "ca-app-pub-xxxxxxxxxx/xxxxx")
interstitial.delegate = self
let request = GADRequest()
interstitial.loadRequest(request)
}
override func viewDidAppear(animated: Bool) {
if (interstitial.isReady && showAd) {
showAd = false
// print("iterstitialMain is ready")
interstitial.presentFromRootViewController(self)
self.createAndLoadInterstitial()
}
else {
showAd = true
}
}
and it works. But it shows an ad every time the user taps on the back button.
I want to show an ad only one time when the user taps on the back button. Would it be better to show an ad after some time instead? For example, every 5 minutes?
Where are you setting showAd to true initially? The logic in your if statement is the main issue.
After you set showAd = false in your if statement, the next time viewDidAppear is called your else statement will be executed, setting showAd back to true.
What you should do is check your Bool, and then check interstitial.isReady. Then, in your GADInterstitial's interstitialDidDismissScreen delegate method you would update your showAd Bool and request another GADInterstitial if you'd like. You say you only want to show one GADInterstitial so requesting another is not necessary. For example:
override func viewDidAppear(animated: Bool) {
if showAd { // Should we show an ad?
if interstitial.isReady { // Is the ad ready?
interstitial.presentFromRootViewController(self)
}
}
else {
// Do nothing
}
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
// Ad was presented and dismissed
print("interstitialDidDismissScreen")
showAd = false // Don't show anymore ads
}
Also, you can change:
let request = GADRequest()
interstitial.loadRequest(request)
to just:
interstitial.loadRequest(GADRequest())
in your createAndLoadInterstitial function.
To answer the second part of your question asking if you should present an ad after some time delay, that is a violation of the AdMob program policies.
Examples of non-compliant implementations:
Interstitial ads that appear before the app has opened or after the app has closed.
Interstitial ads that are triggered after a user closes another interstitial ad.
Interstitial ads loading unexpectedly while a user is viewing the app’s content. Remember to only serve interstitials between pages of content.
Interstitial ads that trigger after every user click.
Interstitial ads that appear during periods of game play or heavy user interaction.
I've set a button that shows an interstitial Admob when pressed.
That's my code:
-Declaration
var AdsInterstitial:GADInterstitial!
-View did load
AdsInterstitial = GADInterstitial(adUnitID: "Id sample number")
let request = GADRequest()
AdsInterstitial.loadRequest(request)
-Button Pressed
AdsInterstitial.presentFromRootViewController(self)
AdsInterstitial = NewInterstitial()
-Function that generates new Ad
func NewInterstitial() -> GADInterstitial{
let AdsInterstitial = GADInterstitial(adUnitID: "Id sample number")
AdsInterstitial.loadRequest(GADRequest())
return AdsInterstitial
}
When I click the button I get this error: " Cannot present interstitial. It is not ready."
Can you help me?
The error message you are getting means you are pressing the button to show ads too soon. When you are pressing the button you should have an if statement checking if the ad is ready or not like this.
if AdsInterstitial.isReady {
AdsInterstitial.presentFromRootViewController(self)
}
Also instead of creating the new Interstitial while the ad is being displayed you should create the new one when they press the "X" button like this
func interstitialDidDismissScreen(ad: GADInterstitial!) {
AdsInterstitial = createAndLoadInterstitial()
}
For more information you can visit Googles site here.