The problem
To avoid violating Google AdMob’s invalid traffic policy when testing an iOS application, you can use demo ads or test devices to verify your implementation code.
Another way to achieve the check your code is to programmatically setup the iOS device as a test device for adMob at the start of your iOS app ...
Enabling Google AdMob's test mode
Demo ad units
Use the Demo ad unit ID corresponding to the Ad format you want to display in your app.
For example, for a banner ad, the id listed in the Demo ad units list is ca-app-pub-3940256099942544/2934735716
Add your test device in the AdMob UI
To automatically enable a device test mode, you can also use the AdMob UI.
- In the menu on the left, select the
Settings
item. - Then, select the
Test Devices
tab, at the top of the page. - Click on the
Add test device
button. - Finally, add the device to the list by filling the form and clicking
Save
.
※ The device's IDFA is necessary to add this device to the test device list.
Add your test device programmatically
Sometimes, you don't know the device's IDFA, in this case enabling the device test mode programmatically is a useful option.
To set a device or a list of devices as test devices:
- First, get the Google Mobile Ads SDK settings shared instance with
GADMobileAds.sharedInstance()
. - Then, get the request configuration common to all requests with
.requestConfiguration
. - Finally, assign a list of identifiers for the devices you want to use in test mode to the list of identifiers corresponding to test devices which will always request test ads returned by
.testDeviceIdentifiers
Like that:
import GoogleMobileAds
...
GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers =
[ "2077ef9a63d2b398840261c8221a0c9b" ] // Sample device ID
※ The test device identifier for the current device is logged to the console when the first ad request is made.
But how to get the test device identifiers?
Get the test device IDFA
An IDFA is simply an Identifier for Advertising for a device issued by iOS to be used by advertisers to uniquely identify a device.
To get a device IDFA:
- First, get the shared instance of the object that contains the advertising identifier with
ASIdentifierManager.shared()
. - Then, get the advertising identifier with
.advertisingIdentifier
. - Finally, get the advertising identifier's UUID string returned by
.uuidString
Like that:
import AdSupport
...
var idfa: String = ASIdentifierManager.shared().advertisingIdentifier.uuidString
As you can see the UUID string format of a sample IDFA like EA7583CD-A667-48BC-B806-42ECB2B48606
is different from the format of the sample device ID 2077ef9a63d2b398840261c8221a0c9b
we used previously. We will have to convert the IDFA.
Converting an IDFA into a test device identifier
It turns out that the test device ID used by Google AdMob is simply a md5 hash of the IDFA UUID string we just acquired:
import CryptoKit
...
var deviceId: String = Insecure.MD5.hash(
data: idfa.data(using: .utf8)!
)
.map { String(format: "%02hhx", $0) }
.joined()
Then you can use the resulting device ID string in the testDeviceIdentifiers
to enable the current device's test mode.
Complete Code
import SwiftUI
import AdSupport
import CryptoKit
import GoogleMobileAds
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
let persistenceController = PersistenceController.shared
var body: some Scene {
WindowGroup {
MyAppView()
.environment(\.managedObjectContext, persistenceController.container.viewContext)
}
}
}
class AppDelegate: NSObject, UIApplicationDelegate {
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil)
GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [
Insecure.MD5.hash(
data: ASIdentifierManager.shared().advertisingIdentifier.uuidString.data(using: .utf8)!
)
.map { String(format: "%02hhx", $0) }
.joined()
];
return true
}
}
Last words
Don't forget to remove the code enabling the test mode before releasing your app!