在 SwiftUI (5) 和 Xcode (12.4) 中实现 AdMob 插页式广告

Ada*_*eed 1 admob swiftui

我正在努力在我的应用程序中实现插页式广告,但对 AdMob 提供的文档和新的 SwiftUI 应用程序结构遇到了一些困惑。

这是app.swift文件,显示我已经实现了 GoogleMobileAds 并在didFinishLaunchingWithOptions方法中启动了它。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的ContentView.swift文件中,我创建了间隙变量,如下所示:

@State var interstitial: GADInterstitialAd?
Run Code Online (Sandbox Code Playgroud)

然后,在视图的主堆栈上,我调用onAppear(perform:)加载广告:

.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
                           }
    )
})
Run Code Online (Sandbox Code Playgroud)

但是,我不断收到此错误:

“无法将‘ContentView’类型的值分配给‘GADFullScreenContentDelegate’类型?”

在尝试了几种不同的解决方法并尝试查找与我类似的设置后,我感觉有点无能为力。AdMob 文档仍然只展示如何实现它,UIViewController但我想弄清楚如何在 SwiftUI 中执行此操作。

Ser*_*kov 6

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

在应用程序中任意位置的AdsViewModel中切换showInterstitial参数,就会显示广告。