Skip to content

Commit

Permalink
Rework bannerview
Browse files Browse the repository at this point in the history
  • Loading branch information
0xWDG committed Oct 20, 2024
1 parent 30be2f8 commit 021544f
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 91 deletions.
5 changes: 3 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ let package = Package(
.package(
name: "GoogleMobileAds",
url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git",
from: "11.2.0"
)
from: "11.1.0"
),
// .package(name: "GoogleMobileAds", url: "https://github.com/googleads/swift-package-manager-google-mobile-ads.git", revision: "11.1.0")
],

targets: [
Expand Down
5 changes: 4 additions & 1 deletion Sources/Admob-SwiftUI/AdConsent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import UserMessagingPlatform
@MainActor
class GoogleMobileAdsConsentManager: NSObject {
static let shared = GoogleMobileAdsConsentManager()

var isMobileAdsStartCalled = false

var canRequestAds: Bool {
Expand Down Expand Up @@ -65,7 +66,9 @@ class GoogleMobileAdsConsentManager: NSObject {
from viewController: UIViewController, completionHandler: @escaping (Error?) -> Void
) {
UMPConsentForm.presentPrivacyOptionsForm(
from: viewController, completionHandler: completionHandler)
from: viewController,
completionHandler: completionHandler
)
}

/// Method to initialize the Google Mobile Ads SDK. The SDK should only be initialized once.
Expand Down
14 changes: 11 additions & 3 deletions Sources/Admob-SwiftUI/AdConsentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,22 @@

import SwiftUI
import GoogleMobileAds
import OSLog

struct AdConsentView: View {
@EnvironmentObject
private var adHelper: AdHelper

@State private var hasViewAppeared = false
@State
private var hasViewAppeared = false

private let formViewControllerRepresentable = FormViewControllerRepresentable()

private let logger = Logger(
subsystem: "nl.wesleydegroot.Admob-SwiftUI",
category: "AdConsentView"
)

var formViewControllerRepresentableView: some View {
formViewControllerRepresentable
.frame(width: .zero, height: .zero)
Expand All @@ -41,7 +49,7 @@ struct AdConsentView: View {
) { (formError) in
guard let formError else { return }

print(formError.localizedDescription)
logger.fault("\(formError.localizedDescription)")
}
}

Expand All @@ -55,7 +63,7 @@ struct AdConsentView: View {

if let consentError {
// Consent gathering failed.
print("Error: \(consentError.localizedDescription)")
logger.fault("Error: \(consentError.localizedDescription)")
}

GoogleMobileAdsConsentManager.shared.startGoogleMobileAdsSDK()
Expand Down
15 changes: 11 additions & 4 deletions Sources/Admob-SwiftUI/AdHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@ import GoogleMobileAds
import UserMessagingPlatform

open class AdHelper: ObservableObject {
@Published public var haveConsent: Bool = false
@Published public var showingAd: Bool = true
@Published public var adUnitId: String = ""
@Published public var adWidth: CGFloat = .zero
@Published
public var haveConsent: Bool = false

@Published
public var showingAd: Bool = true

@Published
public var adUnitId: String = ""

@Published
public var adWidth: CGFloat = .zero

public var updateConsent: (() -> Void) = { }

Expand Down
5 changes: 1 addition & 4 deletions Sources/Admob-SwiftUI/AdView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,8 @@ public struct AdView<Content: View>: View {
if adHelper.haveConsent {
VStack {
Spacer()
BannerView(adUnitID: adHelper.adUnitId)
.background(.clear)
.frame(width: 320, height: adHelper.adHeight)
BannerView()
.padding(.bottom, adHelper.adHeight + 1)
.opacity(adHelper.showingAd ? 1 : 0)
.environmentObject(adHelper)
}
}
Expand Down
126 changes: 49 additions & 77 deletions Sources/Admob-SwiftUI/BannerView.swift
Original file line number Diff line number Diff line change
@@ -1,94 +1,66 @@
//
// BannerView.swift
// BannerViewController.swift
// Admob-SwiftUI
//
// Created by Wesley de Groot on 11/02/2024.
// Created by Wesley de Groot on 21/08/2024.
// https://wesleydegroot.nl
//
// Usage & Example: https://wesleydegroot.nl/blog/post/Admob-in-SwiftUI

import SwiftUI
import GoogleMobileAds
import AppTrackingTransparency
import OSLog

struct BannerView: UIViewControllerRepresentable {
public struct BannerView: View {
@EnvironmentObject
private var adHelper: AdHelper

@State
private var viewWidth: CGFloat = .zero

@State
var adUnitID: String

private let bannerView = GADBannerView()

func makeUIViewController(context: Context) -> some UIViewController {
let bannerViewController = BannerViewController()
bannerView.adUnitID = adUnitID
bannerView.rootViewController = bannerViewController
bannerView.delegate = context.coordinator

bannerViewController.view.backgroundColor = .clear
bannerViewController.view.addSubview(bannerView)
bannerViewController.delegate = context.coordinator

return bannerViewController
}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
guard viewWidth != .zero else {
return
var adHelper: AdHelper

private let logger = Logger(
subsystem: "nl.wesleydegroot.Admob-SwiftUI",
category: "BannerView"
)

public init() { }

public var body: some View {
ZStack {
AdConsentView()
.onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in
ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
logStatus(status: status)
})
}
.environmentObject(adHelper)

if adHelper.haveConsent {
InternalBannerView(adUnitID: adHelper.adUnitId)
.frame(
width: GADAdSizeBanner.size.width,
height: GADAdSizeBanner.size.height
)
.opacity(adHelper.showingAd ? 1 : 0)
.environmentObject(adHelper)
}
}

// Request a banner ad with the updated viewWidth.
bannerView.adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth)
bannerView.load(GADRequest())
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
.frame(
width: adHelper.showingAd ? nil : 1,
height: adHelper.showingAd ? nil : 1
)
}

class Coordinator: NSObject, BannerViewControllerWidthDelegate, GADBannerViewDelegate {
let parent: BannerView

init(_ parent: BannerView) {
self.parent = parent
}

// MARK: - BannerViewControllerWidthDelegate methods

func bannerViewController(_ bannerViewController: BannerViewController, didUpdate width: CGFloat) {
// Pass the viewWidth from Coordinator to BannerView.
parent.viewWidth = width
}

// MARK: - GADBannerViewDelegate methods

func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
print("DID RECEIVE AD")
parent.adHelper.showingAd = true
}

func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
print("DID NOT RECEIVE AD: \(error.localizedDescription)")
parent.adHelper.showingAd = false
}

func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
print("\(#function) called")
}

func bannerViewWillPresentScreen(_ bannerView: GADBannerView) {
print("\(#function) called")
}

func bannerViewWillDismissScreen(_ bannerView: GADBannerView) {
print("\(#function) called")
}

func bannerViewDidDismissScreen(_ bannerView: GADBannerView) {
print("\(#function) called")
func logStatus(status: ATTrackingManager.AuthorizationStatus) {
switch status {
case .notDetermined:
logger.debug("Status: Not determined")
case .authorized:
logger.debug("Status: Authorized")
case .denied:
logger.debug("Status: Denied")
case .restricted:
logger.debug("Status: Restricted")
@unknown default:
logger.debug("Status: Unknown")
}
}
}
100 changes: 100 additions & 0 deletions Sources/Admob-SwiftUI/InternalBannerView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
//
// BannerView.swift
// Admob-SwiftUI
//
// Created by Wesley de Groot on 11/02/2024.
// https://wesleydegroot.nl
//
// Usage & Example: https://wesleydegroot.nl/blog/post/Admob-in-SwiftUI

import SwiftUI
import GoogleMobileAds
import OSLog

struct InternalBannerView: UIViewControllerRepresentable {
@EnvironmentObject
private var adHelper: AdHelper

@State
private var viewWidth: CGFloat = .zero

@State
var adUnitID: String

private let bannerView = GADBannerView()

private let logger = Logger(
subsystem: "nl.wesleydegroot.Admob-SwiftUI",
category: "InternalBannerView"
)

func makeUIViewController(context: Context) -> some UIViewController {
let bannerViewController = BannerViewController()
bannerView.adUnitID = adUnitID
bannerView.rootViewController = bannerViewController
bannerView.delegate = context.coordinator

bannerViewController.view.backgroundColor = .clear
bannerViewController.view.addSubview(bannerView)
bannerViewController.delegate = context.coordinator

return bannerViewController
}

func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
guard viewWidth != .zero else {
return
}

// Request a banner ad with the updated viewWidth.
bannerView.adSize = GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(viewWidth)
bannerView.load(GADRequest())
}

func makeCoordinator() -> Coordinator {
Coordinator(self)
}

class Coordinator: NSObject, BannerViewControllerWidthDelegate, GADBannerViewDelegate {
let parent: InternalBannerView

init(_ parent: InternalBannerView) {
self.parent = parent
}

// MARK: - BannerViewControllerWidthDelegate methods

func bannerViewController(_ bannerViewController: BannerViewController, didUpdate width: CGFloat) {
// Pass the viewWidth from Coordinator to BannerView.
parent.viewWidth = width
}

// MARK: - GADBannerViewDelegate methods

func bannerViewDidReceiveAd(_ bannerView: GADBannerView) {
parent.logger.debug("DID RECEIVE AD")
parent.adHelper.showingAd = true
}

func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) {
parent.logger.error("DID NOT RECEIVE AD: \(error.localizedDescription)")
parent.adHelper.showingAd = false
}

func bannerViewDidRecordImpression(_ bannerView: GADBannerView) {
parent.logger.debug("\(#function) called")
}

func bannerViewWillPresentScreen(_ bannerView: GADBannerView) {
parent.logger.debug("\(#function) called")
}

func bannerViewWillDismissScreen(_ bannerView: GADBannerView) {
parent.logger.debug("\(#function) called")
}

func bannerViewDidDismissScreen(_ bannerView: GADBannerView) {
parent.logger.debug("\(#function) called")
}
}
}

0 comments on commit 021544f

Please sign in to comment.