Swift 3, SpriteKit, Google Interstitial ad never ready - ios

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.

Related

App crashes when AdMob interstitial begins

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!

Unable to load rewarded video ads sometimes

I've launched an iOS app, but I am having problems loading rewarded video ads using the Google Mobile Ads SDK.
When a player clicks the button to see a video ad, the player is shown a video very few times. Most of the time, the user is shown an error of Admob being unable to fill the request:
Error Domain=com.google.ads Code=1 "Request Error: No ad to show."
Sometimes it will take them several clicks before getting one, and sometimes they just can't get one no matter how many clicks. This issue happens more with my rewarded videos, but it also happens with my banner ad. Sometimes Google is unable to provide me with a banner ad. Does anyone know why this is not working?
My code for ads:
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
let scene = MainMenu(view.bounds.size, self, nil)
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = false
view.showsNodeCount = false
view.showsPhysics = false
GADRewardBasedVideoAd.sharedInstance().delegate = self
GADRewardBasedVideoAd.sharedInstance().load(getRequest(),
withAdUnitID: rewardAdId)
// In this case, we instantiate the banner with desired ad size.
if GameViewController.bannerView == nil {
GameViewController.bannerView = GADBannerView(adSize: kGADAdSizeBanner)
GameViewController.bannerView.adUnitID = bannerId
GameViewController.bannerView.rootViewController = self
GameViewController.bannerView.load(getRequest())
GameViewController.bannerView.isHidden = true
addBannerViewToView(GameViewController.bannerView)
}
authenticateLocalPlayer()
QuestManager().checkForRefresh()
}
}
public func getRequest() -> GADRequest {
let request = GADRequest()
return request
}
public func displayRewardedVideo() {
if GADRewardBasedVideoAd.sharedInstance().isReady {
GADRewardBasedVideoAd.sharedInstance().present(fromRootViewController: self)
} else {
GameViewController.loadVideo()
}
}
public static func loadVideo(){
if !GADRewardBasedVideoAd.sharedInstance().isReady {
GADRewardBasedVideoAd.sharedInstance().load(GADRequest(),
withAdUnitID: rewardAdId)
}
}
func rewardBasedVideoAdDidClose(_ rewardBasedVideoAd: GADRewardBasedVideoAd) {
GADRewardBasedVideoAd.sharedInstance().load(getRequest(),
withAdUnitID: rewardAdId)
if let scene = gameScene {
scene.audioManager.unmmute()
}
print("Video did close")
}
I am currently working at a certain company that provides tons of free mobile applications with Admob as a freelancer, so I'm quite adept with it.
Anyways, what I've learned from the manager of my company (they also have a Google Admob consultant there), is that the ad to be shown in an app can be dependent to the country that the user is in. For instance, I'm here in South East Asia and they're in Europe. I experience some times when I do not receive a banner ad, but in their place, they always receive all types of ads.
As long as your project is complying the the Google Admob's rules (e.g. do not display interstitial ad after the other one at a short gap of time), and you receive some ad at least once every while, then I believe you're doing fine.
I hope this helps.

Some interstitial ads won't close or dismiss when hitting 'X'

I have an app that shows an interstitial ad after a few pages on a UIPageViewController. Usually the ad is OK, and I can dismiss it by its own 'X' button. But there are some ads (especially the ones about games like Clash of Kings, i've noticed) that will not dismiss some times regardless of how many times I hit the 'X' button.
I even have a time that dismisses modals such as the interstitial after 5 seconds, but with these particular ads, it won't work.
Here is my code:
func createAndLoadInterstitial() -> GADInterstitial {
let interst = GADInterstitial(adUnitID: "..")
interst.delegate = self
let request = GADRequest()
interst.load(request)
return interst
}
func showInterstitial() {
if interstitial.isReady {
self.interstitial.present(fromRootViewController: self)
self.timer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.dismissInterstitial), userInfo: nil, repeats: false)
} else {
print("Ad wasn't ready")
}
}
func dismissInterstitial() {
self.dismiss(animated: true, completion: nil) //THIS WORKS FINE EXCEPT FOR THESE PARTICULAR ADS.
}
I tried making sure it was on the main thread as well with DispatchQueue.main.async but again, this doesn't work every time.
Is there a way to fix this, or something I might be missing?
Thanks.
Haven't used ads before but saw this behavior in games. Things that come to my mind:
Does it have a delegate method which is called and then you dismiss the ad?
If there is no delegate method then might be that the ad is 'cheating' and shows the 'x' button with no purpose.
Possible solution: How about creating a transparent view and create a gesture recognizer and close when it's tapped?

How to show AdMob Interstitial one time on back button tap

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.

Admob Ads not displaying iOS

I have a banner ad and an interstitial ad. They are appearing when I use the adUnitID's for testing purposes that AdMob gives you, but neither of them are showing when I use live ads. The banner just doesn't appear at all. When the interstitial ad appears, it is just completely black. The adUnitID's are correct. The ads on my other apps are currently appearing just fine. The problem occurs both when I use the iOS simulator and my device. Any ideas?
var interstitial: GADInterstitial!
func createAndLoadAd() -> GADInterstitial{
let ad = GADInterstitial(adUnitID: "ca-app-pub-7863284438864645/1835730011")
let request = GADRequest()
ad.loadRequest(request)
return ad
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
authenticateLocalPlayer()
self.bannerView.adUnitID = "ca-app-pub-7863284438864645/9358996816"
self.bannerView.rootViewController = self
let request: GADRequest = GADRequest()
self.bannerView.loadRequest(request)
self.interstitial = self.createAndLoadAd()
}
override func viewDidAppear(animated: Bool) {
_ = GADRequest()
//request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
showAd()
}
func showAd(){
if(self.interstitial.isReady){
print("ad ready")
self.interstitial.presentFromRootViewController(self)
}
else{
print("ad not ready")
self.interstitial = createAndLoadAd()
}
}
This is an aside, because my problem looked similar, but was not.
App ID is NOT the same as Ad Unit ID.
And, stupidly, they BOTH start with ca-app-pub- and a lot of numbers. I was using the App ID which I can guarantee 100% does NOT work.
Yes, I feel pretty silly, but the folks at Google should have made them dissimilar.
replace adUnitID with your own ad unit id in your Admob account.
make sure you setup payment method, otherwise the ads wont show up
They have both IDs that contains "~" telda and "/" slash

Resources