skip to Main Content

I am working on implementing Interstitial ads in my app and running into some confusion with the docs provided by Admob and the new SwiftUI app structure.

Here is the app.swift file, showing that I’ve implemented the GoogleMobileAds and started it in the didFinishLaunchingWithOptions method.

import SwiftUI
import GoogleMobileAds

@main
struct adamsCalcApp: App {
    var calculator = Calculator()
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView().environmentObject(calculator)
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        // Setup google admob instance
        GADMobileAds.sharedInstance().start(completionHandler: nil)
        return true
    }

}

In my ContentView.swift File, I have the interstitial variable created like…

 @State var interstitial: GADInterstitialAd?

Then on the main stack in the view, I call onAppear(perform: ) to load the ad, however I keep getting this error.

.onAppear(perform: {
            let request = GADRequest()
                    GADInterstitialAd.load(withAdUnitID:"ca-app-pub-3940256099942544/4411468910",
                                                request: request,
                                      completionHandler: { [self] ad, error in
                                        if let error = error {
                                          return
                                        }
                                        interstitial = ad
                                        interstitial?.fullScreenContentDelegate = self
                                      }
                    )

        })

"Cannot assign value of type ‘ContentView’ to type
‘GADFullScreenContentDelegate?’"

I am feeling a bit clueless after trying a few different workarounds and trying to look up a setup that is like mine, AdMob docs still show how to implement with class ViewControllers and I would like to figure out how to do this is SwiftUI.

2

Answers


  1. Chosen as BEST ANSWER

    In order to use the Admob docs with the newest SwiftUI release, you need to change this line...

            .onAppear(perform: {
                        let request = GADRequest()
                                GADInterstitialAd.load(withAdUnitID:"ca-app-pub-3940256099942544/4411468910",
                                                            request: request,
                                                  completionHandler: { [self] ad, error in
                                                    if let error = error {
                                                      return
                                                    }
                                         // Change these two lines of code
                                         interstitial = ad
                                                    
                                         interstitial?.fullScreenContentDelegate = self
                                         // To...
                                         interstitial = ad
                                         let root = UIApplication.shared.windows.first?.rootViewController                                        
                          self.interstitial!.present(fromRootViewController: root!)
                                                  }
                                )
            
                    })
    

  2. import SwiftUI
    import GoogleMobileAds
    import AppTrackingTransparency
    import AdSupport
    
    class AdsManager: NSObject, ObservableObject {
        
        private struct AdMobConstant {
            static let interstitial1ID = "..."
        }
        
        final class Interstitial: NSObject, GADFullScreenContentDelegate, ObservableObject {
    
            private var interstitial: GADInterstitialAd?
            
            override init() {
                super.init()
                requestInterstitialAds()
            }
    
            func requestInterstitialAds() {
                let request = GADRequest()
                request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene
                ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
                    GADInterstitialAd.load(withAdUnitID: AdMobConstant.interstitial1ID, request: request, completionHandler: { [self] ad, error in
                        if let error = error {
                            print("Failed to load interstitial ad with error: (error.localizedDescription)")
                            return
                        }
                        interstitial = ad
                        interstitial?.fullScreenContentDelegate = self
                    })
                })
            }
            func showAd() {
                let root = UIApplication.shared.windows.last?.rootViewController
                if let fullScreenAds = interstitial {
                    fullScreenAds.present(fromRootViewController: root!)
                } else {
                    print("not ready")
                }
            }
            
        }
        
        
    }
    
    
    class AdsViewModel: ObservableObject {
        static let shared = AdsViewModel()
        @Published var interstitial = AdsManager.Interstitial()
        @Published var showInterstitial = false {
            didSet {
                if showInterstitial {
                    interstitial.showAd()
                    showInterstitial = false
                } else {
                    interstitial.requestInterstitialAds()
                }
            }
        }
    }
    
    @main
    struct YourApp: App {
        let adsVM = AdsViewModel.shared
        init() {
            GADMobileAds.sharedInstance().start(completionHandler: nil)
        }
    
        var body: some Scene {
            WindowGroup {
                ContentView()
                    .environmentObject(adsVM)
        }
    }
    

    Toggle the showInterstitial parameter in the AdsViewModel anywhere in the application and the advertisement will be shown.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search