swiftadmobswiftuibanner-ads

Determine When Google Banner Ad is loaded in SwiftUI


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!


Solution

  • 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)")}
            }
        }
    }