I try to integrate Interstitial ad in swiftUI, I create the UIViewControllerRepresentable class and the UIViewController.
https://developers.google.com/admob/ios/interstitial#show_the_ad
But I don't know how to show the ad once the ad ready and loaded.
in Admob documentation i have
if interstitial.isReady {
interstitial.present(fromRootViewController: viewController)
} else {
print("Ad wasn't ready")
}
but I don't know where put his code and how input the view in my swiftUI view
import SwiftUI
import UIKit
import GoogleMobileAds
final class GADInterstitialViewController: UIViewControllerRepresentable {
public var interstitial: GADInterstitial!
public func makeUIViewController(context: UIViewControllerRepresentableContext<GADInterstitialViewController>) -> UIViewController {
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
let viewController = UIViewController()
let request = GADRequest()
interstitial.load(request)
return viewController
}
func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<GADInterstitialViewController>) {
}
}
struct Transit: View {
var body: some View {
ZStack{
GADInterstitialViewController()
.frame(width: screen.width, height: screen.height, alignment: .center)
}
}
}
The solution doesn't work for me when the interstitial is not in the root view. After searching around, finally I could make it work.
I use an EnvironmentObject to hold the Interstitial
Xcode 11.5, Swift 5
import Foundation
import GoogleMobileAds
class SharedValues:ObservableObject{
@Published var interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
@Published var popInterstitial = false
}
And then create a struct or viewcontroller class to hold the ViewController/View which is used to display the Interstitial specifically. The code looks much but most of them are boilerplate codes.
struct InterstitialVC:UIViewControllerRepresentable{
@EnvironmentObject var sharing:SharedValues
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
if sharing.popInterstitial{
showAd(uiViewController)
}
}
func makeUIViewController(context: Context) -> some UIViewController {
let vc = UIViewController()
vc.view.frame = UIScreen.main.bounds
sharing.interstitial.delegate = context.coordinator
return vc
}
Here we implement the GADInterstitialDelegate, the Coordinator thing looks exotic to me the first time I see it. But when you get your hand dirty and you will find it very straight forward and convenient. You need the Coordinator thing to communicate between the delegate/UIKit and SwiftUI.
sharing.interstitial.delegate = context.coordinator
Above is the code you set the coordinator as your GADInterstitialDelegate, it may work good even if you don't implement the delegate methods. But those methods help a lot when you research and debug how things work.
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator:NSObject,GADInterstitialDelegate{
var parent:InterstitialVC
init(_ parent: InterstitialVC) {
self.parent = parent
}
func interstitialDidReceiveAd(_ ad: GADInterstitial) {
//do your things
parent.sharing.popInterstitial = true
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
//do your things
let request = GADRequest()
parent.sharing.interstitial.load(request)
}
func interstitialWillPresentScreen(_ ad: GADInterstitial) {
//do your things
}
func interstitialDidFail(toPresentScreen ad: GADInterstitial) {
//do your things
}
}
Almost all boilerplate codes. Notice that the Coordinate class is inside the InterstitialVC struct. I use the delegate method to determine when to pop and pre-load the Ad again.
func showAd(_ controller:UIViewController){
if sharing.interstitial.isReady{
sharing.interstitial.present(fromRootViewController: controller)
sharing.popInterstitial = false
}else{
print("Not Ready Yet")
}
}
}
In the ContentView or other views, find a good place to put/hide the InterstitialVC() before it pops. Voila
struct ContentView: View {
@State var showInterstitial = true
@EnvironmentObject var sharing:SharedValues
var body: some View {
ZStack{
// if showInterstitial{
// InterstitialVC()
// .edgesIgnoringSafeArea(.all)
// }
NavigationView{
List{
NavigationLink("Show Second View", destination: SecondView())
}
}
}.onAppear{
let request = GADRequest()
self.sharing.interstitial.load(request)
}
}
}
import SwiftUI
import GoogleMobileAds
struct SecondView: View {
@EnvironmentObject var sharing:SharedValues
@State var showInterstitial = true
var body: some View {
ZStack{
if showInterstitial{
InterstitialVC()
}
Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/)
}
.background(Color.yellow)
.onAppear{
let request = GADRequest()
parent.sharing.interstitial.load(request)
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With