swiftUI APP 集成 Google 移动广告 Admob (二)

@高效码农  December 8, 2021

书接上文 ~~~~

激励广告

创建激励广告几乎与插页式广告相同。唯一的区别是,对于奖励广告,我们需要创建一个函数,该函数将在授予奖励时运行。

就像插页式广告一样,我们需要创建一个RewardedAdObject来处理广告的加载。

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

现在,我们将使用这个对象来创建RewardedAdView。

class RewardedAdView: NSObject, UIViewControllerRepresentable, GADFullScreenContentDelegate {
    
    let rewardedAd = RewardedAd.shared.rewardedAd
    @Binding var isPresented: Bool
    let adUnitId: String
  
    //This is the variable for our reward function
    let rewardFunc: (() -> Void)
    
    init(isPresented: Binding<Bool>, adUnitId: String, rewardFunc: @escaping (() -> Void)) {
        self._isPresented = isPresented
        self.adUnitId = adUnitId
        self.rewardFunc = rewardFunc
        
        super.init()
        
        rewardedAd?.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 = rewardedAd {
            ad.present(fromRootViewController: root) {
                //This calls the reward function once the ad has been played for long enough
                self.rewardFunc()
            }
        } else {
            print("Ad not ready")
            self.isPresented.toggle()
        }
    }
    
    func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
        RewardedAd.shared.loadAd(withAdUnitId: adUnitId)
        
        isPresented.toggle()
    }
}

现在我们有了视图,我们需要一种简单的方法在我们的应用程序中呈现它们。为此,我们将创建一个类似于.sheet()修饰符的自定义修饰符。
测试时,使用激励测试广告单元 ID:ca-app-pub-3940256099942544/1712485313

全屏修改器 FullScreenModifier

让我们开始创建将由修改器创建的视图。

struct FullScreenModifier<Parent: View>: View {
    @Binding var isPresented: Bool
    @State var adType: AdType
    
    //Select adType
    enum AdType {
        case interstitial
        case rewarded
    }
    
    var rewardFunc: () -> Void
    var adUnitId: String
  
    //The parent is the view that you are presenting over
    //Think of this as your presenting view controller
    var parent: Parent 
    
    var body: some View {
        ZStack {
            parent
            
            if isPresented {
                EmptyView()
                    .edgesIgnoringSafeArea(.all)
                
                if adType == .rewarded {
                    RewardedAdView(isPresented: $isPresented, adUnitId: adUnitId, rewardFunc: rewardFunc)
                        .edgesIgnoringSafeArea(.all)
                } else if adType == .interstitial {
                    InterstitialAdView(isPresented: $isPresented, adUnitId: adUnitId)
                }
            }
        }
        .onAppear {
            //Initialize the ads as soon as the view appears
            if adType == .rewarded {
                RewardedAd.shared.loadAd(withAdUnitId: adUnitId)
            } else if adType == .interstitial {
                InterstitialAd.shared.loadAd(withAdUnitId: adUnitId)
            }
        }
    }
}

现在,我们需要做的最后一件事是添加修饰符本身。

extension View {
    public func presentRewardedAd(isPresented: Binding<Bool>, adUnitId: String, rewardFunc: @escaping (() -> Void)) -> some View {
        FullScreenModifier(isPresented: isPresented, adType: .rewarded, rewardFunc: rewardFunc, adUnitId: adUnitId, parent: self)
    }
    
    public func presentInterstitialAd(isPresented: Binding<Bool>, adUnitId: String) -> some View {
        FullScreenModifier(isPresented: isPresented, adType: .interstitial, rewardFunc: {}, adUnitId: adUnitId, parent: self)
    }
}

恭喜,就是这样!现在,您可以轻松地将 Admob/Google 移动广告集成到您的 SwiftUI 应用程序中,如下所示。

struct ContentView: View {
    @State var showRewardedAd: Bool = false
    @State var showIntersitialAd: Bool = false
    @State var rewardGranted: Bool = false
    
    var body: some View {
        ZStack {
            VStack {
                if rewardGranted {
                    Text("Here's a gift")
                } else {
                    Button("Get a Reward") {
                        showRewardedAd.toggle()
                    }
                }
                
                Button("Show Interstitial Ad") {
                    showIntersitialAd.toggle()
                }
                .padding()
                .foregroundColor(Color(.systemPurple))
            }
            
            SwiftUIBannerAd(adPosition: .bottom, adUnitId: testBannerId)
        }
        .presentRewardedAd(isPresented: $showRewardedAd, adUnitId: testRewardedId) {
            print("Reward Granted")
            rewardGranted.toggle()
        }
        .presentInterstitialAd(isPresented: $showIntersitialAd, adUnitId: testInterstitialId)
    }
}

总结:

以上内容的Git地址为:https://github.com/xugj-gits/SwiftUIMobileAds

请勿在用户加载应用和退出应用时展示插页式广告。也就是说插页式广告不允许作为开屏广告使用!

以下是指向每种格式的特定测试广告素材的演示广告单元:

广告格式演示广告单元ID
应用打开ca-app-pub-3940256099942544/5662855259
横幅ca-app-pub-3940256099942544/2934735716
插页式ca-app-pub-3940256099942544/4411468910
插页式视频ca-app-pub-3940256099942544/5135589807
有奖ca-app-pub-3940256099942544/1712485313
奖励插页式广告ca-app-pub-3940256099942544/6978759866
原生高级ca-app-pub-3940256099942544/3986624511
原生高级视频ca-app-pub-3940256099942544/2521693316


评论已关闭