AdMob Banner Ad not Showing Swift 3 - ios

I am working on a SpriteKit game and am implementing banner ads via AdMob (Google Firebase). I have followed Google's tutorials here and here on setting up your first ad request, but when I run the app on either the sim or my device (iPhone 6s), the banner does not show up. Per the tutorials, I implemented the banner view via the Storyboard and the rest was set up programmatically. Below is the code of my view controller.
Q: Why isn't my banner showing?
Follow-up Q: Is it possible to show the banner only on certain SKScenes?
import UIKit
import SpriteKit
import GoogleMobileAds
class GameViewController: UIViewController, GADBannerViewDelegate {
#IBOutlet weak var bannerView: GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
print("Google Mobile Ads SDK version: " + GADRequest.sdkVersion())
bannerView.delegate = self
bannerView.adUnitID = "ca-app-pub-9474695450721030/1823667708"
bannerView.rootViewController = self
let req = GADRequest()
req.testDevices = ["91fbd46dff1179ce0a5e7226cea1ee0b", kGADSimulatorID]
req.tag(forChildDirectedTreatment: true)
bannerView.load(GADRequest())
view.addSubview(bannerView)
showBanner()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let skView = self.view as? SKView {
if skView.scene == nil {
let aspectRatio = view.bounds.size.height / view.bounds.size.width
let scene = MenuScene(size: CGSize(width: 750, height: 750 * aspectRatio))
scene.scaleMode = .aspectFill
skView.ignoresSiblingOrder = true
if kDebug {
skView.showsFPS = true
skView.showsDrawCount = true
skView.showsNodeCount = true
skView.showsPhysics = true
}
let transition = SKTransition.fade(with: SKColor.black, duration: 0.5)
skView.presentScene(scene, transition: transition)
}
}
}
func showBanner() {
bannerView.isHidden = false
let request = GADRequest()
request.testDevices = ["2077ef9a63d2b398840261c8221a0c9b"]
bannerView.load(request)
}
func hideBanner() {
bannerView.isHidden = true
}
}

First of all, you don't need to request a new banner every time you run showAd(). Simply unhide it. The ad you load on launch will remain for the whole lifecycle, and automatically refreshes.
Second, in your viewDidLoad code, you're initializing a banner ad, then loading a completely new one. Make sure that you're loading the same request that you were setting up.
As for calling functions inside your GameViewController from an SKScene, take a look at this: Call GameViewController function from SKScene

Just in case anyone is not seeing the ads after updating the SDK. From my end, I was able to resolve it after much investigation. It is worth noticing that the function name changes after updating the SDK.
The old function is
func adViewDidReceiveAd(_ bannerView: GADBannerView)
The new function is
func bannerViewDidReceiveAd(_ bannerView: GADBannerView)

Related

AdMob doesnt show up in my SpriteKit game

I tried to implement a banner with AdMob into my SpriteKit Game. I added a banner in the GameViewController.swift just like shown in the code underneath, but the banner doesn't show up in my simulator.
What am I missing? I am using Swift 4.
class GameViewController: UIViewController {
var banner:GADBannerView!
override func viewDidLoad() {
super.viewDidLoad()
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
if let scene = SKScene(fileNamed: "GameScene") {
// Set the scale mode to scale to fit the window
scene.scaleMode = .aspectFill
// Present the scene
view.presentScene(scene)
}
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
banner = GADBannerView(adSize: kGADAdSizeSmartBannerPortrait)
banner.adUnitID = "here is my unit ID -> copy paste so cant be wrong"
banner.rootViewController = self
let req:GADRequest = GADRequest()
banner.load(req)
banner.frame = CGRect(x: 0, y: view.bounds.height - banner.frame.size.height, width: banner.frame.size.width, height: banner.frame.size.height)
view.addSubview(banner)
}
}
I think you forget to declare your ViewController as it conforms to GADBannerViewDelegate
class GameViewController: UIViewController, GADBannerViewDelegate {
can you try again after conforming to the protocol?

SKScene switches when displaying interstitial ad with admob with Swift

I am making a game with SpriteKit in Swift and I am having trouble when displaying the ad. The ad shows up when the player dies, as it is supposed to, but instead of staying in the current scene (GameScene) when I close it, it switches out to the MainMenu scene for some reason. Actually, if you watch closely, you can see that the "game over" text appears and as the ad slides up to display, it switches to the MainMenu scene. I saw the post here and tried what the answers said (moving everything from ViewWillLayoutSubviews to ViewDidLoad, etc) and it didn't work. Any ideas? Thanks.
Here is all of the code involving the ad in GameViewController:
class GameViewController: UIViewController, UIAlertViewDelegate, GADInterstitialDelegate {
var musicPlayer = AVAudioPlayer()
var musicUrl = Bundle.main.url(forResource: "Loops2.mp3", withExtension: nil)
var interstitial: GADInterstitial!
override func viewDidLoad() {
super.viewDidLoad()
interstitial = loadAd()
NotificationCenter.default.addObserver(self, selector: #selector(self.playerDied), name: NSNotification.Name("ShowAd"), object: nil)
NotificationCenter.default.post(name: NSNotification.Name("ShowingAd"), object: nil)
super.viewWillLayoutSubviews()
let skView = self.view as! SKView
skView.ignoresSiblingOrder = true
skView.showsFPS = true
skView.showsNodeCount = true
let mainMenu = MainMenu()
mainMenu.scaleMode = .aspectFill
mainMenu.size = view.bounds.size
skView.presentScene(mainMenu)
}
func playerDied() {
if self.interstitial.isReady {
self.interstitial.present(fromRootViewController: self)
}
}
func loadAd() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/1033173712")
interstitial.delegate = self
interstitial.load(GADRequest())
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
NotificationCenter.default.post(name: NSNotification.Name("AdDismissed"), object: nil)
interstitial = loadAd()
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if let url = musicUrl {
try! musicPlayer = AVAudioPlayer(contentsOf: url)
musicPlayer.numberOfLoops = -1
musicPlayer.prepareToPlay()
musicPlayer.play()
}
}
I use the NotificationCenter to signal GameViewController when to display the ad. I don't think that the code from GameScene is needed, but if you think it would be helpful, just ask. Thanks!

Using AdMob interstitial ads in iOS game applications and Swift

Okay, I've spent days now doing this. I've gone through admob's tutorials, youtube, stack exchange, everything and I cannot find a solution to my problem.
I'm trying to implement admob's interstitial ads into my iOS game application. The code compiles, builds, runs, the game is played, but ads will not show up. This is my GameViewController.swift
import UIKit
import SpriteKit
import GoogleMobileAds
class GameViewController: UIViewController, GADInterstitialDelegate {
//AD STUFF-----------------------------vBELOWv----------------------------------------------
//AD STUFF-----------------------------vBELOWv----------------------------------------------
var interstitialAd: GADInterstitial?
func createInterstitialAd() -> GADInterstitial {
let request = GADRequest()
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-******")
request.testDevices = [kGADSimulatorID, "C966DEAC-A2FD-4FBA-80B5-802B7E394C6D", "F3E1897A-3556-4704-9C85-3D70B4672F44","090DCEE5-6B1C-4DFB-83CE-FE800A242008", "1B93E43B-E9B3-4482-8B11-4F3614A26EA2"]
interstitial.delegate = self
interstitial.loadRequest(request)
return interstitial
}
//func to show the ad
func showAd() {
if interstitialAd != nil {
if interstitialAd!.isReady{
interstitialAd?.presentFromRootViewController(self)
}
else {print("found not ready")}
}
}
//func to pre-load new ad - calls automatically when closes an ad
func interstitialWillDismissScreen(ad: GADInterstitial!) {
interstitialAd = createInterstitialAd()
}
//AD STUFF--------------------------^ABOVE^--------------------------------------------------
//AD STUFF--------------------------^ABOVE^--------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
interstitialAd = createInterstitialAd()
if let scene = GameScene(fileNamed:"GameScene") {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = true
skView.showsNodeCount = true
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
scene.size = self.view.bounds.size
skView.presentScene(scene)
}
}
This is how I'm calling it to my GameScene
//makes the restart button appear
func createRestartBTN(){
restartBTN = SKSpriteNode(color: SKColor.clearColor(), size: CGSize(width: 200, height: 100))
restartBTN.position = CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMidY(self.frame))
restartBTN.zPosition = 10
addChild(restartBTN)
createReplayText()
varForGVC.showAd()
}
So when the game is over, a function makes a restart button appear. Then I want my interstitial ad to pop up so the user has to exit the interstitial ad to hit the replay button. That variable varForGVC is an implemented earlier in the GameScene.swift by varForGVC = GameViewController()
I have my app synced with Firebase and admob. I have the GoogleService-Info.plist in my root. I have the list of required frameworks for admob in my root as well. I have pod installed with Firebase. I've tried putting the code I'm using in my GameViewController into my GameScene.swift and it did not work there either. I don't know if this matters, but my game has a Main Screen, a Rules screen only accessible via the main screen, then the user hits a Play button to begin playing the game in another Screen (the GameScene). My check for .isReady does not return found not ready. I need some help with this issue. For now, I'm going to try to reinstall the frameworks and see if that's it.
This is how I work with interstitial ads from AdMob - using extension. I think it's way more clean solution. Hope it will help you!
GameViewController.swift
class GameViewController: UIViewController {
var interstitial: GADInterstitial?
override func viewDidLoad() {
createInterstitial()
}
func presentInterstitial() {
guard let interstitial = self.interstitial where interstitial.isReady else {
return
}
dispatch_async(dispatch_get_main_queue(), {
interstitial.presentFromRootViewController(self)
})
}
}
GameViewController+GADInterstitialDelegate.swift
import GoogleMobileAds
extension GameViewController: GADInterstitialDelegate {
func interstitial(ad: GADInterstitial!, didFailToReceiveAdWithError error: GADRequestError!) {
print("\(#function): \(error.localizedDescription)")
}
func interstitialDidDismissScreen(ad: GADInterstitial!) {
// Recycle interstitial
createInterstitial()
unpauseGame() // Some method from GameViewController
}
func interstitialWillPresentScreen(ad: GADInterstitial!) {
pauseGame() // Some method from GameViewController
}
func createInterstitial() {
interstitial = GADInterstitial(adUnitID: interstitialAdUnitID)
interstitial!.loadRequest(AdMobHelper.createRequest())
interstitial!.delegate = self
}
}
And the last part - AdMobHelper.swift
import GoogleMobileAds
let interstitialAdUnitID = "Some Id"
class AdMobHelper {
static func createRequest() -> GADRequest {
let request = GADRequest()
request.testDevices = ["Check this in your logs"]
return request
}
}
I figured it out finally. I used NSNotifcationCenter. I put in an observer in my GameViewController.swift in my viewDidLoad function, then a receiver where I wanted it to pop up.

iAd didFailToReceiveAdWithError not working sometimes, displays white box

I'm using Swift and SpriteKit, and everything is made inside my GameViewController and GameScene.
This is all code concerning the ads inside my GameViewController:
class GameViewController: UIViewController, ADBannerViewDelegate, GADBannerViewDelegate {
var adBannerView: ADBannerView!
var gadBannerView: GADBannerView!
var bannerDisplayed = false
var bannerNow = "iAd"
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GameScene.unarchiveFromFile("GameScene") as? GameScene {
// Configure the view.
let skView = self.view as! SKView
skView.showsFPS = false
skView.showsNodeCount = false
/* Sprite Kit applies additional optimizations to improve rendering performance */
skView.ignoresSiblingOrder = true
/* Set the scale mode to scale to fit the window */
scene.scaleMode = .AspectFill
if((UIDevice.currentDevice().userInterfaceIdiom == .Phone) && (UIScreen.mainScreen().bounds.height <= 480)) {
println("<= iPhone 4S")
scene.size.height = skView.bounds.size.height * 2
scene.size.width = skView.bounds.size.width * 2
}
NSNotificationCenter.defaultCenter().addObserver(self, selector: "hideADBanner", name: "hideAd", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "showADBanner", name: "showAd", object: nil)
self.adBannerView = self.loadAds()
skView.presentScene(scene)
println(gadBannerView)
}
}
func loadAds()->ADBannerView{
var adBannerView2 = ADBannerView(frame: CGRect.zeroRect)
adBannerView2.center = CGPoint(x: adBannerView2.center.x, y: view!.bounds.size.height - adBannerView2.frame.size.height / 2)
adBannerView2.delegate = self
adBannerView2.hidden = true
bannerNow = "iAd"
self.view?.addSubview(adBannerView2)
return adBannerView2
}
func bannerViewActionShouldBegin(banner: ADBannerView!, willLeaveApplication willLeave: Bool) -> Bool {
println("left for ad")
return true
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
println("ad did load.")
println("Delegate: \(adBannerView.delegate)")
adBannerView.hidden = false
//gadBannerView?.removeFromSuperview()
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
//adBannerView.removeFromSuperview()
//self.gadBannerView = self.createGADBanner()
}
func createGADBanner()->GADBannerView {
var ad = GADBannerView()
ad = GADBannerView(frame: CGRectMake(0, 0, self.view.frame.size.width, 50))
ad.delegate = self
ad.rootViewController = self
ad.adUnitID = "xxxxxxxxxxx"
bannerNow = "GAD"
var reqAd = GADRequest()
//reqAd.testDevices = [GAD_SIMULATOR_ID] // If you want test ad's
ad.loadRequest(reqAd)
self.view.addSubview(ad)
println(ad)
return ad
}
func adViewDidReceiveAd(view: GADBannerView!) {
println("adViewDidReceiveAd:\(view)");
bannerDisplayed = true
relayoutViews()
}
func adView(bannerView: GADBannerView!, didFailToReceiveAdWithError error: GADRequestError!) {
gadBannerView.removeFromSuperview()
}
func relayoutViews() {
if (bannerDisplayed) {
var bannerFrame = gadBannerView!.frame
bannerFrame.origin.x = 0
bannerFrame.origin.y = self.view.bounds.size.height - bannerFrame.size.height
gadBannerView!.frame = bannerFrame
}
}
func hideADBanner() {
println(self.gadBannerView)
println(bannerNow)
//adBannerView?.hidden = true
//gadBannerView?.hidden = true
adBannerView?.removeFromSuperview()
gadBannerView?.removeFromSuperview()
}
func showADBanner() {
self.adBannerView = self.loadAds()
//adBannerView?.hidden = false
//gadBannerView?.hidden = false
}
So my plan is to get ads from AdMob when iAd is not working, but the problem is that my iAd "always works", even though I've changed the fill-rate inside the Developer tools in my iPhone.
When iAd loads the ad it works fine, the function bannerViewDidLoadAd() is called and the ad is displayed. Although sometimes when I load iAd it says that I've entered bannerViewDidLoadAd() but it only displays a white "box" with the iAd logo in the bottom. Now, this is not what I want because then AdMob is never gonna show. The println always put out the same delegate so it seems like that works at least.
This view never refreshes because everything, as I said, is handled in the GameScene where it's just removing and adding nodes.
Thank you!
You're over complicating things immensely with bool's, unnecessary functions, and it looks like you've actually created two ADBannerViews once in Interface Builder, self.adBannerView, and once programmatically, var adBannerView: ADBannerView!.
I've created an example with comments to help you along the way. Whats happening here is we are creating an ADBannerView, setting it up once in our viewDidLoad, and then hiding/showing our ADBannerView depending on if it receives an ad from the iAd network or not. I've left out the AdMob implementation as it should be pretty straight forward now.
import UIKit
import iAd // Import iAd
class ViewController: UIViewController, ADBannerViewDelegate { // Include the delegate for our ADBannerView
var adBannerView = ADBannerView() // Create our ADBannerView
// Create your GADBannerView here
override func viewDidLoad() {
super.viewDidLoad()
loadAds()
}
func loadAds() {
// Setup our ADBannerView
adBannerView = ADBannerView(frame: CGRect.zeroRect)
adBannerView.center = CGPoint(x: view.bounds.size.width / 2, y: view.bounds.size.height - adBannerView.frame.size.height / 2)
adBannerView.delegate = self
adBannerView.hidden = true
view.addSubview(adBannerView)
// Setup your GADBannerView here in the same manner
}
func bannerViewDidLoadAd(banner: ADBannerView!) {
println("bannerViewDidLoadAd")
// We received an ad from iAd. Lets show our banner
adBannerView.hidden = false
// Hide your GADBannerView here
}
func bannerViewActionDidFinish(banner: ADBannerView!) {
println("bannerViewActionDidFinish")
}
func bannerView(banner: ADBannerView!, didFailToReceiveAdWithError error: NSError!) {
println("didFailToReceiveAdWithError: \(error)")
// We failed to receive an ad from iAd. Lets hide our banner and print the error
adBannerView.hidden = true
// Show your GADBannerView here
}

How to create a iAd banner?

I'm still a noob developper and I just finished my little game and now I want to integrate AdBanner.
With the code bellow the banner appear and disappear instantly. I tried on another ViewController/GameScene and the banner appear and stay. I can't understand the problem.
My Game is under gravity. It is to shoot falling objects from the bottom of the screen.
Someone can help me ?
Here my GameViewController code :
import UIKit
import SpriteKit
import AVFoundation
import iAd
var defaults = NSUserDefaults()
var highscore = defaults.integerForKey("highscore")
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.canDisplayBannerAds = true
var skView = self.originalContentView as SKView
var scene:SKScene = GameScene(size: skView.bounds.size)
skView.showsFPS = false
skView.showsNodeCount = false
skView.showsPhysics = false
let turbulence = SKFieldNode.turbulenceFieldWithSmoothness(0.1, animationSpeed: 0.1)
scene.addChild(turbulence)
let noise = SKFieldNode.turbulenceFieldWithSmoothness(0.4, animationSpeed: 0.1)
scene.addChild(noise)
skView.presentScene(scene)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override func prefersStatusBarHidden() -> Bool {
return true
}
}
You can add the iAd framework into the project. Then link it into your file with:
import iAd
Then you add this line of code whenever you want the ad to come onto the screen:
self.canDisplayBannerAds = true
This will automatically give you an add at the bottom of the screen.

Resources