2

Starting with iOS16, there was a problem with the implementation of AdMob interstitial advertising. I am using the SwiftUI framework. I looked at many sources, but unfortunately I did not find a solution. Link to on a similar topic, but without a solution. On iOS 15 everything works fine, but on iOS 16 the app crashes with the following error:

SwiftUI/UIViewControllerRepresentable.swift:332: Fatal error: UIViewControllerRepresentables must be value types: InterstitialAdView 2022-11-20 15:34:32.811071+0300 MyApp[38437:1156286] SwiftUI/UIViewControllerRepresentable.swift:332: Fatal error: UIViewControllerRepresentables must be value types: InterstitialAdView

As I understand, to implement the UIViewControllerRepresentable protocol, you must use a struct, but the NSObject and GADFullScreenContentDelegate protocols can only be applied in a class. Question: how can the code be modified to meet the above requirements? I am using the following code (original from here):

// InterstitialAdView
final class InterstitialAdView: NSObject, UIViewControllerRepresentable, GADFullScreenContentDelegate {

    //Here's the Ad Object we just created
    let interstitialAd = InterstitialAd.shared.interstitialAd
    @Binding var isPresented: Bool
    var adUnitId: String

init(isPresented: Binding<Bool>, adUnitId: String) {
    self._isPresented = isPresented
    self.adUnitId = adUnitId
    super.init()

    interstitialAd?.fullScreenContentDelegate = self //Set this view as the delegate for the ad
}

//Make's a SwiftUI View from a UIViewController
func makeUIViewController(context: Context) -> UIViewController {
    let view = UIViewController()
    //Show the ad after a slight delay to ensure the ad is loaded and ready to present
    DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) {
        self.showAd(from: view)
    }
    return view
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}

//Presents the ad if it can, otherwise dismisses so the user's experience is not interrupted
func showAd(from root: UIViewController) {
    if let ad = interstitialAd {
        ad.present(fromRootViewController: root)
    } else {
        self.isPresented.toggle()
    }
}

func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    //Prepares another ad for the next time view presented
    InterstitialAd.shared.loadAd(withAdUnitId: adUnitId)
    //Dismisses the view once ad dismissed
    isPresented.toggle()
    }
}
Aleksei
  • 79
  • 6
  • Change the class to a struct and put all the delegate code in the coordinator – lorem ipsum Nov 20 '22 at 14:21
  • Does this answer your question? [Implementing AdMob Interstitial Ads in SwiftUI (5) and Xcode (12.4)](https://stackoverflow.com/questions/68168522/implementing-admob-interstitial-ads-in-swiftui-5-and-xcode-12-4) – lorem ipsum Nov 20 '22 at 14:25

0 Answers0