Why?
We are now required to add a GDPR consent message to our apps after 16 Jan 2024 because of EEA requirements to show ads to users in Europe.
If we don’t do so, the revenue from the ads will be largely impacted.
How?
You can watch this official video from Google AdMob to learn how to implement this.
However, like always, Google documentation just shows you the UIKit way to add it, not SwiftUI.
SwiftUI Example
After a day of exploring, I finally got it to work using pure SwiftUI.
It is actually pretty simple:
import SwiftUI
import UserMessagingPlatform
struct ContentView: View {
@AppStorage("gdprConsentShown") var gdprConsentShown = false
var body: some View {
VStack {
}
.onAppear {
gdprConsentCheck()
}
}
func gdprConsentCheck() {
guard !gdprConsentShown else { return }
// Create a UMPRequestParameters object.
let parameters = UMPRequestParameters()
let debugSettings = UMPDebugSettings ()
// - This is for mimicking EEA users when you're outside the EU.
// - Use a simulator so you can read the consent form.
debugSettings.geography = .EEA
parameters.debugSettings = debugSettings
// Set tag for under age of consent. false means users are not under the age of consent. If you turn this on, no consent form is presented.
parameters.tagForUnderAgeOfConsent = false
// Request an update for the consent information.
UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(with: parameters) { (requestConsentError) in
if let consentError = requestConsentError {
// Consent gathering failed.
return print("Error: \(consentError.localizedDescription)")
}
// Load and present the consent form.
loadAndPresentConsentForm()
}
}
func loadAndPresentConsentForm() {
UMPConsentForm.load { (form, loadError) in
if let error = loadError {
// Consent form could not be loaded.
return print("Error: \(error.localizedDescription)")
}
if let form = form {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene {
if let window = windowScene.windows.first {
if let rootViewController = window.rootViewController {
form.present(from: rootViewController) { (dismissError) in
if let error = dismissError {
// Consent form could not be dismissed.
print("Error: \(error.localizedDescription)")
gdprConsentShown = false
} else {
// Consent form was dismissed.
// Check the consent status.
let status = UMPConsentInformation.sharedInstance.consentStatus
print("Consent status: \(status)")
gdprConsentShown = true
}
}
}
}
}
}
}
}
}
Yes, the if let looks ugly, because it’s half ChatGPTed, but you get the idea. I modified it and put everything in another view.
So for every app I’m making, I just copy and paste that view. Here’s how I would use it in my main view:
//for ads and consent form
@State var readyToShow = false
@State private var bannerView: BannerView? = nil
/////
context
.onAppear() {
// create the banner onAppear, readyToShow is false by default
bannerView = BannerView(readyToShow: $readyToShow, adUnitID: "ca-app-pub-yourKeyHere")
// This performs the consent form logic inside the bannerView, if everything goes well, toggle readyToShow to true.
bannerView?.gdprConsentCheck()
}
.toolbar {
ToolbarItem(placement: .bottomBar) {
// So only users who passed the consent form will see this banner ad.
if !adRemoved && readyToShow{
bannerView
.frame(width: GADAdSizeBanner.size.width, height: GADAdSizeBanner.size.height)
}
}
}
Personalised Ads
To control whether to show personalized ads, we used to set the ads request option to something like this:
import GoogleMobileAds
let request = GADRequest()
let extras = GADExtras()
extras.additionalParameters = ["npa": "1"] // This means no personalized ads are shown
request.register(extras)
Remember, we need to set up ATT for App Store compliance.
However, it serves no purpose to interact with Google AdMob now. It is because when you use UserMessagingPlatform, Google manages the “personalization” on their platform.
“In case this is still helpful for anyone, confirming that using the UMP SDK for Android you do not need to set npa=1. The UMP SDK writes the TCF string to shared preferences (related info at https://support.google.com/admob/answer/9760862), and the Google Mobile Ads SDK reads the TCF string on ad requests.” – Eric, Mobile Ads SDK Team – Read more
That’s what I read on Google AdMob forum.
Although they said It’s for Android, I’d assume it works the same way on iOS.
But still, we need to implement the ATT for Apple anyway, so I’m keeping it for now.
Hope this guide simplifies things a bit and helps you.