简体   繁体   中英

SwiftUI - AdMob Interstitial ad crashes only on iOS 16

I have a view in which there is an interstitial ad that gets presented. 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-09-22 09:33:06.740743+0200 HowRich[47572:2135353] SwiftUI/UIViewControllerRepresentable.swift:332: Fatal error: UIViewControllerRepresentables must be value types: InterstitialAdView (lldb)

And where there's the @main I get this error:

在此处输入图像描述

The code is the following:

InterstitialAdsManager.swift

import GoogleMobileAds
import SwiftUI
import UIKit

class InterstitialAd: NSObject {
    var interstitialAd: GADInterstitialAd?
    
    static let shared = InterstitialAd()
    
    func loadAd(withAdUnitId id: String) {
        let req = GADRequest()
        GADInterstitialAd.load(withAdUnitID: id, request: req) { interstitialAd, err in
            if let err = err {
                print("Failed to load ad with error: \(err)")
                return
            }
            
            self.interstitialAd = interstitialAd
        }
    }
}

final class InterstitialAdView: NSObject, UIViewControllerRepresentable, GADFullScreenContentDelegate {
    
    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
    }
    
    func makeUIViewController(context: Context) -> UIViewController {
        let view = UIViewController()
        
        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1)) {
            self.showAd(from: view)
        }
        
        return view
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        
    }
    
    func showAd(from root: UIViewController) {
        
        if let ad = interstitialAd {
            ad.present(fromRootViewController: root)
        } else {
            print("Ad not ready")
            self.isPresented.toggle()
        }
    }
    
    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        InterstitialAd.shared.loadAd(withAdUnitId: adUnitId)
        
        isPresented.toggle()
    }
}

struct FullScreenModifier<Parent: View>: View {
    @Binding var isPresented: Bool
    
    var adUnitId: String
    var parent: Parent
    
    var body: some View {
        ZStack {
            parent
            
            if isPresented {
                EmptyView()
                    .edgesIgnoringSafeArea(.all)
                
                InterstitialAdView(isPresented: $isPresented, adUnitId: adUnitId)
            }
        }
        .onAppear {
           InterstitialAd.shared.loadAd(withAdUnitId: adUnitId)
        }
    }
}

extension View {
    public func presentInterstitialAd(isPresented: Binding<Bool>, adUnitId: String) -> some View {
        FullScreenModifier(isPresented: isPresented, adUnitId: adUnitId, parent: self)
    }
}

The View with the ad:

struct CheckoutView: View {
   
    @State var showAd = false

  var body: some View {
        ScrollView {
            ZStack {
                VStack {
                  //The view
                   }
                    .onAppear {
            if UserDefaults.standard.string(forKey: "AdCounter") == "0" && UserDefaults.standard.bool(forKey: "AdFree") == false {
                showAd = true
                UserDefaults.standard.setValue("1", forKey: "AdCounter")
            }
            UserDefaults.standard.setValue("0", forKey: "AdCounter")
         }
        .presentInterstitialAd(isPresented: $showAd, adUnitId: myIntersId)
}
}
}

I have updated all pods to the latest available versions (Google Mobile Ads SDK is version 9.11.0). What's causing the crash on iOS 16 and how can I fix it? Thanks

The solution is to change

final class InterstitialAdView: NSObject, UIViewControllerRepresentable, GADFullScreenContentDelegate {

into

struct InterstitialAdView: NSObject, UIViewControllerRepresentable, GADFullScreenContentDelegate {

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM