3

This is coded in Swift

I have successfully added a Google Banner Ad to a settings page in my application. I have implemented it below:

import Foundation
import SwiftUI
import GoogleMobileAds

struct AdView : UIViewRepresentable
{
    @Binding var AdLoaded : Bool

    func makeUIView(context: UIViewRepresentableContext<AdView>) -> GADBannerView
    {
        let banner = GADBannerView(adSize: kGADAdSizeBanner)
        banner.adUnitID = "realAdId"
        banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        return banner
    }

    func updateUIView(_ uiView: GADBannerView, context: UIViewRepresentableContext<AdView>){}

    public func adViewDidReceiveAd(_ bannerView: GADBannerView)
    {
        AdLoaded = true
        if (DEBUG_ADS ) { print("Banner Ad Did Find Ad!") }
    }

    public func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError)
    {
        AdLoaded = false
        if (DEBUG_ADS ) { print(error) }
    }
}

I am aware that since I don't have GADBannerViewDelegate in this struct, that I don't have access to the functions I have implemented (adViewDidReceiveAd and adView...didFailToReceiveAdWithError). They never get called as is.

I have messed around a lot but I can not find a proper way to implemented these delegate functions.

My intended functionality is to implement this AdView in my settings page as such:

if ( someBindingVariable??? )
{
    AdView(AdLoaded: self.$AdLoaded)
}

The way it currently works is that a space is left for the AdView before it is loaded. Once the ad is loaded, the space is filled with the ad. I want the space to only be added once an ad is loaded.

Thanks for you help, and let me know if I am not clear on something!

1 Answers1

2

From @Asperi comment, I implemented a Coordinator with my AdView and it worked!

See below:

import Foundation
import SwiftUI
import GoogleMobileAds

struct AdView : UIViewRepresentable
{
    @Binding public var AdLoaded : Bool
    public var bannerId : String

    func makeCoordinator() -> Coordinator
    {
        Coordinator(self)
    }

    func makeUIView(context: UIViewRepresentableContext<AdView>) -> GADBannerView
    {
        let banner = GADBannerView(adSize: kGADAdSizeBanner)
        banner.adUnitID = bannerId
        banner.rootViewController = UIApplication.shared.windows.first?.rootViewController
        banner.load(GADRequest())
        banner.delegate = context.coordinator
        return banner
    }

    func updateUIView(_ uiView: GADBannerView, context: UIViewRepresentableContext<AdView>){}

    class Coordinator: NSObject, GADBannerViewDelegate
    {
        var parent: AdView

        init(_ parent: AdView)
        {
            self.parent = parent
        }

        func adViewDidReceiveAd(_ bannerView: GADBannerView)
        {
            parent.AdLoaded = true
            if ( DEBUG_ADS ) { print("Ad View Did Receive Ad For ID: \(parent.bannerId)")}
        }

        func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError)
        {
            parent.AdLoaded = false
            if ( DEBUG_ADS ) { print("Ad View Failed To Receive Ad For ID: \(parent.bannerId)")}
        }
    }
}
  • If I use this code, Xcode prompts an error: Cannot find 'DEBUG_ADS' in scope – Michael Oct 12 '21 at 11:41
  • 1
    Also you have to change func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) for actual implementation of the Ads framework – Michael Oct 12 '21 at 11:43