I’m experiencing a difficulty with Google AdMob in my iOS app the place adaptive banner advertisements typically seem as all black screens. It looks like the advertisements should not loading accurately.
Problem Description:
The issue happens intermittently; typically, the advertisements show accurately, whereas at different occasions, they’re simply black.
I’ve observed that navigating away from the display after which returning, or switching to a different display and again, typically resolves the problem quickly, suggesting it is likely to be associated to the advert loading course of.
For my advert implementation technique, my aim is to have dynamic advertisements that adapt based mostly on whether or not the advert request is fulfilled and whether or not they load accurately.
Implementation Particulars:
Right here’s how I’m presently implementing the advertisements in my app:
import SwiftUI
import GoogleMobileAds
struct AdaptiveBannerAdView: UIViewRepresentable {
var adUnitID: String
@Binding var adHeight: CGFloat
@Binding var isAdLoaded: Bool
var customWidth: CGFloat
var effectiveAdUnitID: String {
ThConstants.Admob.useRealIds ? adUnitID : ThConstants.Admob.testAdaptiveBannerUnitId
}
func makeUIView(context: Context) -> GADBannerView {
// Create a brand new banner view
let bannerView = GADBannerView(adSize: GADAdSizeBanner)
bannerView.adUnitID = effectiveAdUnitID
// Get root view controller utilizing the fashionable method
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.home windows.first?.rootViewController {
bannerView.rootViewController = rootViewController
}
bannerView.delegate = context.coordinator
bannerView.load(GADRequest())
return bannerView
}
func updateUIView(_ uiView: GADBannerView, context: Context) {
let adaptiveSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(customWidth)
uiView.adSize = adaptiveSize
uiView.body.measurement.top = adaptiveSize.measurement.top
DispatchQueue.predominant.async {
self.adHeight = adaptiveSize.measurement.top
}
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, GADBannerViewDelegate {
var father or mother: AdaptiveBannerAdView
init(_ father or mother: AdaptiveBannerAdView) {
self.father or mother = father or mother
}
func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
DispatchQueue.predominant.async {
self.father or mother.isAdLoaded = true
print("PRODUCTION: Advert loaded efficiently.")
}
}
func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
print("Advert didn't load with error: (error.localizedDescription)")
// Solely set isAdLoaded to false on preliminary load failures
if !self.father or mother.isAdLoaded {
DispatchQueue.predominant.async {
self.father or mother.isAdLoaded = false
}
}
// Retry loading after a delay
DispatchQueue.predominant.asyncAfter(deadline: .now() + 5) {
bannerView.load(GADRequest())
}
}
// New technique to deal with advert rendering points
func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
// Test if the advert content material is seen and never black
DispatchQueue.predominant.asyncAfter(deadline: .now() + 1) {
if bannerView.subviews.isEmpty || bannerView.subviews.first?.backgroundColor == .black {
print("Advert rendered incorrectly. Retrying...")
self.father or mother.isAdLoaded = false
bannerView.load(GADRequest())
}
}
}
}
}
import SwiftUI
// A SwiftUI view that serves as a container for displaying the adaptive banner advert
struct AdContainerView: View {
let adUnitID: String
let customWidth: CGFloat
@State non-public var isAdLoaded: Bool = false
@State non-public var adHeight: CGFloat = 0
var physique: some View {
AdaptiveBannerAdView(
adUnitID: adUnitID,
adHeight: $adHeight,
isAdLoaded: $isAdLoaded,
customWidth: customWidth
)
.body(
width: isAdLoaded ? customWidth : 0,
top: isAdLoaded ? adHeight : 0
)
.onChange(of: isAdLoaded) { newValue in
if !newValue {
// Reset advert top when the advert isn't loaded
adHeight = 0
}
}
.onAppear {
// Reset the advert state when the view reappears
if !isAdLoaded {
adHeight = 0
}
}
}
}
// Logic to show the AdContainerView based mostly on advert availability
if ThConstants.Admob.isAdAvailable {
// If advertisements can be found, create and show the AdContainerView
AdContainerView(
adUnitID: ThConstants.Admob.banner_bottom_wiki, // Move the advert unit ID for the banner
customWidth: screenWidth // Move the calculated width for the banner
)
} else {
/// If you happen to select to not show or request advertisements in any respect
EmptyView() // Render an empty view when advertisements should not obtainable
}