From 42b9673482ab0b7e2fea3f23b5109bf5f5fa4f6d Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Mon, 12 Aug 2024 17:02:53 +0100 Subject: [PATCH] EUID support --- .../GameViewController.swift | 11 ++- .../UID2GoogleGMADevelopmentApp/Info.plist | 2 + Package.swift | 6 +- RELEASE_PROCESS.md | 2 + .../EUIDGMAMediationAdapter.swift | 61 ++++++++++++++ .../UID2GMAMediationAdapter.swift | 11 +-- .../EUIDGMAMediationAdapterTests.swift | 81 +++++++++++++++++++ .../TestData/uid2identity.json | 9 --- .../TestExtensions/DataLoader.swift | 21 ----- UID2GMAPlugin.podspec.json | 4 +- 10 files changed, 166 insertions(+), 42 deletions(-) create mode 100644 Sources/UID2GMAPlugin/EUIDGMAMediationAdapter.swift create mode 100644 Tests/UID2GMAPluginTests/EUIDGMAMediationAdapterTests.swift delete mode 100644 Tests/UID2GMAPluginTests/TestData/uid2identity.json delete mode 100644 Tests/UID2GMAPluginTests/TestExtensions/DataLoader.swift diff --git a/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/GameViewController.swift b/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/GameViewController.swift index b3b3ac8..9da0992 100644 --- a/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/GameViewController.swift +++ b/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/GameViewController.swift @@ -63,6 +63,15 @@ class GameViewController: UIViewController, GADFullScreenContentDelegate { /// Text that indicates current coin count. @IBOutlet weak var coinCountLabel: UILabel! + private let manager: UID2Manager = { + let isEUID = Bundle.main.object(forInfoDictionaryKey: "UID2EnvironmentEUID") as? Bool ?? false + if isEUID { + return EUIDManager.shared + } else { + return UID2Manager.shared + } + }() + override func viewDidLoad() { super.viewDidLoad() @@ -110,7 +119,7 @@ class GameViewController: UIViewController, GADFullScreenContentDelegate { refreshExpires: refreshExpires, refreshResponseKey: uid2IdentityFromFile.refreshResponseKey) - await UID2Manager.shared.setIdentity(uid2Identity) + await manager.setIdentity(uid2Identity) } catch { print("Error loading UID2Identity") } diff --git a/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/Info.plist b/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/Info.plist index 9f87ee0..92a25cd 100644 --- a/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/Info.plist +++ b/Development/UID2GoogleGMADevelopmentApp/UID2GoogleGMADevelopmentApp/Info.plist @@ -2,6 +2,8 @@ + UID2EnvironmentEUID + GADApplicationIdentifier ca-app-pub-3940256099942544~1458002511 SKAdNetworkItems diff --git a/Package.swift b/Package.swift index 1a1cc36..2b82a8d 100644 --- a/Package.swift +++ b/Package.swift @@ -30,9 +30,7 @@ let package = Package( ]), .testTarget( name: "UID2GMAPluginTests", - dependencies: ["UID2GMAPlugin"], - resources: [ - .copy("TestData") - ]) + dependencies: ["UID2GMAPlugin"] + ) ] ) diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 5e5b8e6..57c9b6a 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -15,6 +15,8 @@ Version Numbering follows [Semantic Versioning](https://semver.org) standards. * https://github.com/IABTechLab/uid2-ios-plugin-google-gma/blob/cfc508a79af81d5b8d0aefdb60881567ea08fd24/Package.swift#L18 * Update / Confirm `adapterVersion()` in `UID2GMAMediationAdapter.swift` is set to expected version * https://github.com/IABTechLab/uid2-ios-plugin-google-gma/blob/cfc508a79af81d5b8d0aefdb60881567ea08fd24/Sources/UID2GMAPlugin/UID2GMAMediationAdapter.swift#L40-L46 + * Update / Confirm `adapterVersion()` in `EUIDGMAMediationAdapter.swift` is set to expected version + * https://github.com/IABTechLab/uid2-ios-plugin-google-gma/blob/ed1ffe2c710c58da2867d9ea0b888ecfa1aedefc/Sources/UID2GMAPlugin/EUIDGMAMediationAdapter.swift#L38-L44 * Update / Confirm `version` and `source.tag` in `UID2GMAPlugin.podspec.json` are set to expected version * https://github.com/IABTechLab/uid2-ios-plugin-google-gma/blob/main/UID2GMAPlugin.podspec.jsonL6-L12 * Add and / or Edit any ADRs that support this release diff --git a/Sources/UID2GMAPlugin/EUIDGMAMediationAdapter.swift b/Sources/UID2GMAPlugin/EUIDGMAMediationAdapter.swift new file mode 100644 index 0000000..2326c45 --- /dev/null +++ b/Sources/UID2GMAPlugin/EUIDGMAMediationAdapter.swift @@ -0,0 +1,61 @@ +// +// EUIDGMAMediationAdapter.swift +// + +import Foundation +import GoogleMobileAds +import UID2 + +/// Adapter to connect EUID to Google Mobile Ads +/// https://developers.google.com/admob/ios/open-bidding-adapter +@available(iOS 13, *) +@objc(EUIDGMAMediationAdapter) +class EUIDGMAMediationAdapter: NSObject { + + required override init() { } + +} + +@available(iOS 13, *) +extension EUIDGMAMediationAdapter: GADRTBAdapter { + + static func setUpWith(_ configuration: GADMediationServerConfiguration, completionHandler: @escaping GADMediationAdapterSetUpCompletionBlock) { + + // Ensure UID2Manager has started + _ = EUIDManager.shared + + completionHandler(nil) + } + + func collectSignals(for params: GADRTBRequestParameters, completionHandler: @escaping GADRTBSignalCompletionHandler) { + Task { + guard let advertisingToken = await EUIDManager.shared.getAdvertisingToken() else { + completionHandler(nil, AdvertisingTokenNotFoundError()) + return + } + completionHandler(advertisingToken, nil) + } + } + + static func adapterVersion() -> GADVersionNumber { + var version = GADVersionNumber() + version.majorVersion = 1 + version.minorVersion = 0 + version.patchVersion = 0 + return version + } + + static func adSDKVersion() -> GADVersionNumber { + let uid2Version = UID2SDKProperties.getUID2SDKVersion() + var version = GADVersionNumber() + version.majorVersion = uid2Version.major + version.minorVersion = uid2Version.minor + version.patchVersion = uid2Version.patch + return version + } + + static func networkExtrasClass() -> GADAdNetworkExtras.Type? { + return nil + } + +} diff --git a/Sources/UID2GMAPlugin/UID2GMAMediationAdapter.swift b/Sources/UID2GMAPlugin/UID2GMAMediationAdapter.swift index e17a10e..54045ab 100644 --- a/Sources/UID2GMAPlugin/UID2GMAMediationAdapter.swift +++ b/Sources/UID2GMAPlugin/UID2GMAMediationAdapter.swift @@ -42,17 +42,18 @@ extension UID2GMAMediationAdapter: GADRTBAdapter { static func adapterVersion() -> GADVersionNumber { var version = GADVersionNumber() - version.majorVersion = 0 - version.minorVersion = 4 + version.majorVersion = 1 + version.minorVersion = 0 version.patchVersion = 0 return version } static func adSDKVersion() -> GADVersionNumber { + let uid2Version = UID2SDKProperties.getUID2SDKVersion() var version = GADVersionNumber() - version.majorVersion = UID2SDKProperties.getUID2SDKVersion().major - version.minorVersion = UID2SDKProperties.getUID2SDKVersion().minor - version.patchVersion = UID2SDKProperties.getUID2SDKVersion().patch + version.majorVersion = uid2Version.major + version.minorVersion = uid2Version.minor + version.patchVersion = uid2Version.patch return version } diff --git a/Tests/UID2GMAPluginTests/EUIDGMAMediationAdapterTests.swift b/Tests/UID2GMAPluginTests/EUIDGMAMediationAdapterTests.swift new file mode 100644 index 0000000..e5f3b35 --- /dev/null +++ b/Tests/UID2GMAPluginTests/EUIDGMAMediationAdapterTests.swift @@ -0,0 +1,81 @@ +// +// EUIDGMAMediationAdapterTests.swift +// + +import XCTest +import GoogleMobileAds +import UID2 +@testable import UID2GMAPlugin + +final class EUIDGMAMediationAdapterTests: XCTestCase { + + /// 🟩 - GMA Adapter Request Signal Success + func testRequestSignalsSuccess() async throws { + // Seed the sample UID2Identity data in the UID2Manager + await EUIDManager.shared.setAutomaticRefreshEnabled(false) + await EUIDManager.shared.setIdentity( + UID2Identity( + advertisingToken: "euid-test-token", + refreshToken: "refresh-token", + identityExpires: Date(timeIntervalSinceNow: 60 * 60).millisecondsSince1970, + refreshFrom: Date(timeIntervalSinceNow: 60 * 40).millisecondsSince1970, + refreshExpires: Date(timeIntervalSinceNow: 60 * 50).millisecondsSince1970, + refreshResponseKey: "" + ) + ) + + let signal = try await EUIDGMAMediationAdapter().collectSignals(for: GADRTBRequestParameters()) + + // Confirm that Adapter returns expected data + XCTAssertEqual("euid-test-token", signal) + } + + /// 🟥 - GMA Adapter Request Signal Error No Identity + func testRequestSignalsNoIdentity() async throws { + // Ensure no identity is set + await EUIDManager.shared.resetIdentity() + + let result = await Task { + try await EUIDGMAMediationAdapter().collectSignals(for: GADRTBRequestParameters()) + }.result + XCTAssertThrowsError(try result.get()) { error in + let adapterError = error as? AdvertisingTokenNotFoundError + XCTAssertEqual(AdvertisingTokenNotFoundError(), adapterError) + } + } + + /// 🟥 - GMA Adapter Request Signal No Advertising Token Erro + func testRequestSignalsNoAdvertisingToken() async throws { + // Set an identity with an invalid advertisingToken + await EUIDManager.shared.setAutomaticRefreshEnabled(false) + await EUIDManager.shared.setIdentity( + UID2Identity( + advertisingToken: "", + refreshToken: "refresh-token", + identityExpires: Date(timeIntervalSinceNow: 60 * 60).millisecondsSince1970, + refreshFrom: Date(timeIntervalSinceNow: 60 * 40).millisecondsSince1970, + refreshExpires: Date(timeIntervalSinceNow: 60 * 50).millisecondsSince1970, + refreshResponseKey: "" + ) + ) + + let result = await Task { + try await EUIDGMAMediationAdapter().collectSignals(for: GADRTBRequestParameters()) + }.result + XCTAssertThrowsError(try result.get()) { error in + let adapterError = error as? AdvertisingTokenNotFoundError + XCTAssertEqual(AdvertisingTokenNotFoundError(), adapterError) + } + } + + /// 🟩 - GMA Adapter Ad SDK Version Check Success + func testAdSDKVersion() async throws { + + let adSDKVersion = EUIDGMAMediationAdapter.adSDKVersion() + let sdkVersion = await EUIDManager.shared.sdkVersion + + XCTAssertEqual(sdkVersion.major, adSDKVersion.majorVersion) + XCTAssertEqual(sdkVersion.minor, adSDKVersion.minorVersion) + XCTAssertEqual(sdkVersion.patch, adSDKVersion.patchVersion) + } +} diff --git a/Tests/UID2GMAPluginTests/TestData/uid2identity.json b/Tests/UID2GMAPluginTests/TestData/uid2identity.json deleted file mode 100644 index cfaad7e..0000000 --- a/Tests/UID2GMAPluginTests/TestData/uid2identity.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "advertising_token": "NewAdvertisingTokenIjb6u6KcMAtd0/4ZIAYkXvFrMdlZVqfb9LNf99B+1ysE/lBzYVt64pxYxjobJMGbh5q/HsKY7KC0Xo5Rb/Vo8HC4dYOoWXyuGUaL7Jmbw4bzh+3pgokelUGyTX19DfArTeIg7n+8cxWQ=", - "refresh_token": "NewRefreshTokenAAAF2c8H5dF8AAAF2c8H5dF8AAAADX393Vw94afoVLL6A+qjdSUEisEKx6t42fLgN+2dmTgUavagz0Q6Kp7ghM989hKhZDyAGjHyuAAwm+CX1cO7DWEtMeNUA9vkWDjcIc8yeDZ+jmBtEaw07x/cxoul6fpv2PQ==", - "identity_expires": 1633643601000, - "refresh_from": 1633643001000, - "refresh_expires": 1636322000000, - "refresh_response_key": "yptCUTBoZm1ffosgCrmuwg==", - "status": "success" -} \ No newline at end of file diff --git a/Tests/UID2GMAPluginTests/TestExtensions/DataLoader.swift b/Tests/UID2GMAPluginTests/TestExtensions/DataLoader.swift deleted file mode 100644 index 63d7669..0000000 --- a/Tests/UID2GMAPluginTests/TestExtensions/DataLoader.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// DataLoader.swift -// -// -// Created by Brad Leege on 3/21/23. -// - -import Foundation - -final class DataLoader { - - static func load(fileName: String, fileExtension: String, _ inDirectory: String = "TestData") throws -> Data { - guard let bundlePath = Bundle.module.path(forResource: fileName, ofType: fileExtension, inDirectory: inDirectory), - let stringData = try String(contentsOfFile: bundlePath).data(using: .utf8) else { - throw "Could not load data from file." - } - - return stringData - } - -} diff --git a/UID2GMAPlugin.podspec.json b/UID2GMAPlugin.podspec.json index 63bb114..005c917 100644 --- a/UID2GMAPlugin.podspec.json +++ b/UID2GMAPlugin.podspec.json @@ -3,13 +3,13 @@ "summary": "A plugin for integrating UID2 and Google GMA into iOS applications.", "homepage": "https://unifiedid.com/", "license": "Apache License, Version 2.0", - "version": "0.4.0", + "version": "1.0.0", "authors": { "David Snabel-Caunt": "dave.snabel-caunt@thetradedesk.com" }, "source": { "git": "https://github.com/IABTechLab/uid2-ios-plugin-google-gma.git", - "tag": "v0.4.0" + "tag": "v1.0.0" }, "platforms": { "ios": "12.0"