One single Google Admob banner for *multiple* ViewControllers

1,151 views
Skip to first unread message

joe2885

unread,
Jun 12, 2017, 9:59:28 AM6/12/17
to Google Mobile Ads SDK Developers

I am looking to load one instance of a Google Admob Banner View throughout multiple View Controllers (including, but not limited to a UITabBarController.)


My attempt is below. I'm using AppDelegate to set the adSize, adUnitID and testDevices. Then in each VC where I want a banner displayed, I set the rootViewController, frame, load request, and then addSubView.


This works, in the fact that the ads show up fine. However, the ads keep changing when I segue or dismiss VC! It appears that a new request is happening everytime VC's change. Which is precisely the result that must be avoided!



AppDelegate



class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var adBannerViewFromAppDelegate = GADBannerView() let loadRequest = GADRequest() func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { adBannerViewFromAppDelegate.adSize = kGADAdSizeSmartBannerPortrait adBannerViewFromAppDelegate.adUnitID = "12345" loadRequest.testDevices = [kGADSimulatorID, myiPhone] } }



ViewController (This has a button to SecondViewController via Push Segue)


import UIKit import GoogleMobileAds class ViewController: UIViewController { let appDelegate = UIApplication.shared.delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) addBannerToView() } func addBannerToView() { appDelegate.adBannerViewFromAppDelegate.rootViewController = self appDelegate.adBannerViewFromAppDelegate.load(appDelegate.loadRequest) appDelegate.adBannerViewFromAppDelegate.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: appDelegate.adBannerViewFromAppDelegate.frame.height) view.addSubview(appDelegate.adBannerViewFromAppDelegate) } }



AppDelegate

import UIKit import GoogleMobileAds class SecondViewController: UIViewController { let appDelegate = UIApplication.shared.delegate as! AppDelegate override func viewDidLoad() { super.viewDidLoad() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) addBannerToView() } @IBAction func closeButtonPressed(_ sender: UIButton) { self.dismiss(animated: true, completion: nil) } func addBannerToView() { appDelegate.adBannerViewFromAppDelegate.rootViewController = self appDelegate.adBannerViewFromAppDelegate.load(appDelegate.loadRequest) appDelegate.adBannerViewFromAppDelegate.frame = CGRect(x: 0, y: 0, width: view.frame.width, height: appDelegate.adBannerViewFromAppDelegate.frame.height) view.addSubview(appDelegate.adBannerViewFromAppDelegate) } }



How can I get one instance of the Banner created in the AppDelegate to display on multiple ViewControllers?
Thanks.

Deepika Uragayala- MobileAds SDK team

unread,
Jun 12, 2017, 3:52:06 PM6/12/17
to Google Mobile Ads SDK Developers
Hi Joe,

I would be able to assist you with this. What you can instead do is have a ParentViewController class, which every UIViewController must extend to and then load the single instance of the Banner AdView from ParentVC. Next, the UIViewController's base UIView must be inserted belowSubView of BannerAdView. The AdView for the ParentVC can be loaded from AppDelegate but the placement must be done in this way.

Regards,
Deepika Uragayala
Mobile Ads SDK Team

joe2885

unread,
Jun 12, 2017, 4:28:01 PM6/12/17
to Google Mobile Ads SDK Developers
Hello Deepika!

Thanks for your assistance here.

"What you can instead do is have a ParentViewController class, which every UIViewController must extend to and then load the single instance of the Banner AdView from ParentVC." - This has been done!

"Next, the UIViewController's base UIView must be inserted belowSubView of BannerAdView. The AdView for the ParentVC can be loaded from AppDelegate but the placement must be done in this way." - I'm not too sure what you mean here.
What do you mean by "base UIView must be inserted below subView of bannerAdView?"


Do you mean in code or storyboard? I'm adding the banner frame via code if that makes a difference.

Joe

Deepika Uragayala- MobileAds SDK team

unread,
Jun 12, 2017, 6:38:45 PM6/12/17
to Google Mobile Ads SDK Developers
Hi Joe,

I meant via the code. So let's say that your ChildVC has a UITableView being added as a subView. Instead of using the view.addSubview, use the view.insertSubview(tableView, belowSubview: bannerAdView). This is just to keep the index of the Banner AdView to be on top.

Regards,
Deepika Uragayala
Mobile Ads SDK Team

Stephen Aldous

unread,
Jun 12, 2017, 9:37:56 PM6/12/17
to Google Mobile Ads SDK Developers
Why not have a parentVC with a containerView and the banner ad below it, and put your tab bar controller in the container?

joe2885

unread,
Jun 13, 2017, 2:12:32 AM6/13/17
to Google Mobile Ads SDK Developers
Thanks for the clarification. The banner is always on top.

My updated code for this is below. I'm still getting the same issue as before. The banners swap to new banners during the segue to the new View Controllers. This needs to be resolved for production, or else people would be able to continually tap tabs and inflate impressions. I need the banners to change only when the impression timer (60 seconds; set inside AdMob) has been reached.

Here's the parent controller that you suggested.

class AdmobUIViewController: UIViewController {


    let appDelegate
= UIApplication.shared.delegate as! AppDelegate
   
   
override func viewDidLoad() {
       
super.viewDidLoad()

       
// Do any additional setup after loading the view.

   
}
   
   
override func viewWillAppear(_ animated: Bool) {
       
super.viewWillAppear(animated)
        addBannerToView
()
   
}

    func addBannerToView
() {
        appDelegate
.adBannerViewFromAppDelegate.rootViewController = self
        appDelegate
.adBannerViewFromAppDelegate.load(appDelegate.loadRequest)

        appDelegate
.adBannerViewFromAppDelegate.frame = CGRect(x: 0.0,
                                                               y
: view.frame.height - appDelegate.adBannerViewFromAppDelegate.frame.height,

                                                               width
: view.frame.width,
                                                               height
: appDelegate.adBannerViewFromAppDelegate.frame.height)
        view
.addSubview(appDelegate.adBannerViewFromAppDelegate)
   
}
   

   
}



View Controller 1. A subclass of the Admob class.

class ViewController: AdmobUIViewController {
   
   
override func viewDidLoad() {
       
super.viewDidLoad()
   
}
   
}



View Controller 2. Also a subclass of the Admob class, with a button to dismiss back to the View Controller 1.

class SecondViewController: AdmobUIViewController {
   
   
override func viewDidLoad() {
       
super.viewDidLoad()

   
}


   
@IBAction func closeButtonPressed(_ sender: UIButton) {
       
self.dismiss(animated: true, completion: nil)
   
}
   

}


AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate {
   
var window: UIWindow?
   
var adBannerViewFromAppDelegate = GADBannerView()
    let loadRequest
= GADRequest()

    func application
(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        adBannerViewFromAppDelegate
.adSize = kGADAdSizeSmartBannerPortrait
        adBannerViewFromAppDelegate
.adUnitID = "12345"

        loadRequest
.testDevices = [kGADSimulatorID]
       
return true
   
}

}


Any suggestions are welcome. Thanks.

joe2885

unread,
Jun 13, 2017, 2:13:33 AM6/13/17
to Google Mobile Ads SDK Developers
Not all of the tabs will contain the Banner. And there are View Controllers outside of the tab bar controller that will contain the same banner.

Deepika Uragayala- MobileAds SDK team

unread,
Jun 13, 2017, 3:18:20 PM6/13/17
to Google Mobile Ads SDK Developers
Hi Joe,

In the func addBannerToView(), you are calling appDelegate.adBannerViewFromAppDelegate.load(appDelegate.loadRequest), which would mean a new instance for every new VC. Instead, create the AdView from a separate class, AppDelegate or any Manager class, and maintain only a single instance of throughout the lifecycle. If not, as suggested above, you can definitely use a container to channel a single instance of the AdView. 

Let me know if you have any other questions.

Regards,
Deepika Uragayala
Mobile Ads SDK Team


joe2885

unread,
Jun 13, 2017, 3:46:31 PM6/13/17
to Google Mobile Ads SDK Developers
That makes sense as to why I keep calling the different ads.
Regarding your solution - can you post a manager class for reusing throughout the lifecycle? I never used that method to create ads. Thanks in advance!

Deepika Uragayala- MobileAds SDK team

unread,
Jun 14, 2017, 3:03:01 PM6/14/17
to Google Mobile Ads SDK Developers
Hi Joe,

I don't have a sample app, but if you can provide one, we will gladly include this.

Regards,
Deepika Uragayala
Mobile Ads SDK Team


joe2885

unread,
Jun 14, 2017, 3:07:22 PM6/14/17
to Google Mobile Ads SDK Developers
Can you shoot me an email? I can respond to it with my practice xcode project. Thanks!
Reply all
Reply to author
Forward
0 new messages