-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
There are no files selected for viewing
This file was deleted.
This file was deleted.
This file was deleted.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
This file was deleted.
This file was deleted.
This file was deleted.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// | ||
// GADMAdapterTeadsBannerAd.swift | ||
// TeadsAdMobAdapter | ||
// | ||
// Created by Thibaud Saint-Etienne on 27/10/2022. | ||
// | ||
|
||
import Foundation | ||
import GoogleMobileAds | ||
import TeadsSDK | ||
|
||
@objc(GADMAdapterTeadsBannerAd) | ||
public final class GADMAdapterTeadsBannerAd: NSObject, GADMediationBannerAd { | ||
/// The Teads Ad network InRead AdView | ||
var bannerAd: TeadsInReadAdView? | ||
|
||
/// The ad event delegate to forward ad rendering events to the Google Mobile Ads SDK. | ||
var delegate: GADMediationBannerAdEventDelegate? | ||
|
||
/// Completion handler called after ad load | ||
var completionHandler: GADMediationBannerLoadCompletionHandler? | ||
|
||
public var view: UIView { | ||
bannerAd ?? UIView() | ||
} | ||
|
||
private var placement: TeadsInReadAdPlacement? | ||
private var adConfiguration: GADMediationBannerAdConfiguration? | ||
|
||
public func loadBanner( | ||
for adConfiguration: GADMediationBannerAdConfiguration, | ||
completionHandler: @escaping GADMediationBannerLoadCompletionHandler | ||
) { | ||
// Check PID | ||
guard let rawPid = adConfiguration.credentials.settings["parameter"] as? String, let pid = Int(rawPid) else { | ||
delegate = completionHandler(nil, TeadsAdapterErrorCode.pidNotFound) | ||
return | ||
} | ||
|
||
self.completionHandler = completionHandler | ||
self.adConfiguration = adConfiguration | ||
|
||
// Prepare ad settings | ||
let adSettings = (adConfiguration.extras as? TeadsAdapterSettings) ?? TeadsAdapterSettings() | ||
adSettings.setIntegation(TeadsAdapterSettings.integrationAdmob, version: GADMobileAds.sharedInstance().sdkVersion) | ||
|
||
let adSize = adConfiguration.adSize | ||
bannerAd = TeadsInReadAdView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: adSize.size.width, height: adSize.size.height))) | ||
|
||
placement = Teads.createInReadPlacement(pid: pid, settings: adSettings.adPlacementSettings, delegate: self) | ||
placement?.requestAd(requestSettings: adSettings.adRequestSettings) | ||
} | ||
} | ||
|
||
extension GADMAdapterTeadsBannerAd: TeadsInReadAdPlacementDelegate { | ||
public func didReceiveAd(ad: TeadsInReadAd, adRatio: TeadsAdRatio) { | ||
ad.delegate = self | ||
bannerAd?.bind(ad) | ||
bannerAd?.updateHeight(with: adRatio) | ||
delegate = completionHandler?(self, nil) | ||
completionHandler = nil | ||
} | ||
|
||
public func didFailToReceiveAd(reason: AdFailReason) { | ||
delegate = completionHandler?(nil, reason) | ||
completionHandler = nil | ||
} | ||
|
||
public func adOpportunityTrackerView(trackerView _: TeadsAdOpportunityTrackerView) { | ||
// adOpportunityTrackerView is handled by TeadsSDK | ||
} | ||
|
||
public func didUpdateRatio(ad _: TeadsInReadAd, adRatio: TeadsAdRatio) { | ||
bannerAd?.updateHeight(with: adRatio) | ||
} | ||
} | ||
|
||
extension GADMAdapterTeadsBannerAd: TeadsAdDelegate { | ||
public func didRecordImpression(ad _: TeadsAd) { | ||
delegate?.reportImpression() | ||
} | ||
|
||
public func didRecordClick(ad _: TeadsAd) { | ||
delegate?.reportClick() | ||
} | ||
|
||
public func willPresentModalView(ad _: TeadsAd) -> UIViewController? { | ||
delegate?.willPresentFullScreenView() | ||
return adConfiguration?.topViewController | ||
} | ||
|
||
public func didCatchError(ad _: TeadsAd, error: Error) { | ||
delegate?.didFailToPresentWithError(error) | ||
} | ||
|
||
public func didExpandedToFullscreen(ad _: TeadsAd) { | ||
delegate?.willPresentFullScreenView() | ||
} | ||
|
||
public func didCollapsedFromFullscreen(ad _: TeadsAd) { | ||
delegate?.didDismissFullScreenView() | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
// | ||
// GADMAdapterTeadsCustomEvent.swift | ||
// TeadsAdMobAdapter | ||
// | ||
// Created by Thibaud Saint-Etienne on 26/10/2022. | ||
// | ||
|
||
import Foundation | ||
import GoogleMobileAds | ||
import TeadsSDK | ||
|
||
@objc(GADMAdapterTeadsCustomEvent) | ||
public class GADMAdapterTeadsCustomEvent: NSObject, GADMediationAdapter { | ||
public static func adSDKVersion() -> GADVersionNumber { | ||
let versionComponents = String(Teads.sdkVersion).components( | ||
separatedBy: ".") | ||
|
||
if versionComponents.count >= 3 { | ||
let majorVersion = Int(versionComponents[0]) ?? 0 | ||
let minorVersion = Int(versionComponents[1]) ?? 0 | ||
let patchVersion = Int(versionComponents[2]) ?? 0 | ||
|
||
return GADVersionNumber( | ||
majorVersion: majorVersion, minorVersion: minorVersion, patchVersion: patchVersion | ||
) | ||
} | ||
|
||
return GADVersionNumber() | ||
} | ||
|
||
public static func adapterVersion() -> GADVersionNumber { | ||
adSDKVersion() | ||
} | ||
|
||
public static func networkExtrasClass() -> GADAdNetworkExtras.Type? { | ||
TeadsAdapterSettings.self | ||
} | ||
|
||
public static func setUpWith( | ||
_: GADMediationServerConfiguration, | ||
completionHandler: @escaping GADMediationAdapterSetUpCompletionBlock | ||
) { | ||
Teads.configure() | ||
completionHandler(nil) | ||
} | ||
|
||
override public required init() { | ||
super.init() | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,253 @@ | ||
// | ||
// GADMAdapterTeadsNativeAd.swift | ||
// TeadsAdMobAdapter | ||
// | ||
// Created by Thibaud Saint-Etienne on 27/10/2022. | ||
// | ||
|
||
import GoogleMobileAds | ||
import TeadsSDK | ||
import UIKit | ||
|
||
@objc(GADMAdapterTeadsNativeAd) | ||
final class GADMAdapterTeadsNativeAd: NSObject, GADMediationNativeAd { | ||
/// The ad event delegate to forward ad rendering events to the Google Mobile Ads SDK. | ||
var delegate: GADMediationNativeAdEventDelegate? | ||
|
||
/// Completion handler called after ad load | ||
var completionHandler: GADMediationNativeLoadCompletionHandler? | ||
|
||
private var placement: TeadsNativeAdPlacement? | ||
private var adConfiguration: GADMediationNativeAdConfiguration? | ||
private var adOpportunityView: TeadsAdOpportunityTrackerView? | ||
|
||
private var mappedImages = [GADNativeAdImage]() | ||
private var mappedIcon: GADNativeAdImage? | ||
private var teadsMediaView: TeadsMediaView? | ||
private var adSettings: TeadsAdapterSettings? | ||
|
||
private weak var viewController: UIViewController? | ||
|
||
var nativeAd: TeadsNativeAd? | ||
|
||
var headline: String? { | ||
nativeAd?.title?.text | ||
} | ||
|
||
var images: [GADNativeAdImage]? { | ||
mappedImages | ||
} | ||
|
||
var body: String? { | ||
nativeAd?.content?.text | ||
} | ||
|
||
var icon: GADNativeAdImage? { | ||
mappedIcon | ||
} | ||
|
||
var callToAction: String? { | ||
nativeAd?.callToAction?.text | ||
} | ||
|
||
var starRating: NSDecimalNumber? { | ||
guard let stringValue = nativeAd?.rating?.text else { | ||
return nil | ||
} | ||
return NSDecimalNumber(string: stringValue) | ||
} | ||
|
||
var store: String? { | ||
nil | ||
} | ||
|
||
var price: String? { | ||
nativeAd?.price?.text | ||
} | ||
|
||
var advertiser: String? { | ||
nativeAd?.sponsored?.text | ||
} | ||
|
||
var extraAssets: [String: Any]? { | ||
nil | ||
} | ||
|
||
var adChoicesView: UIView? { | ||
TeadsAdChoicesView(binding: nativeAd?.adChoices) | ||
} | ||
|
||
var mediaView: UIView? { | ||
// Used to return the mediaView if video content. | ||
teadsMediaView | ||
} | ||
|
||
var mediaContentAspectRatio: CGFloat { | ||
nativeAd?.video?.contentAspectRatio ?? 0 | ||
} | ||
|
||
var hasVideoContent: Bool { | ||
nativeAd?.video != nil | ||
} | ||
|
||
override required init() { | ||
super.init() | ||
} | ||
|
||
func loadNativeAd( | ||
for adConfiguration: GADMediationNativeAdConfiguration, | ||
completionHandler: @escaping GADMediationNativeLoadCompletionHandler | ||
) { | ||
// Check PID | ||
guard let rawPid = adConfiguration.credentials.settings["parameter"] as? String, let pid = Int(rawPid) else { | ||
delegate = completionHandler(nil, TeadsAdapterErrorCode.pidNotFound) | ||
return | ||
} | ||
|
||
self.completionHandler = completionHandler | ||
self.adConfiguration = adConfiguration | ||
|
||
// Prepare ad settings | ||
let adSettings = (adConfiguration.extras as? TeadsAdapterSettings) ?? TeadsAdapterSettings() | ||
adSettings.setIntegation(TeadsAdapterSettings.integrationAdmob, version: GADMobileAds.sharedInstance().sdkVersion) | ||
self.adSettings = adSettings | ||
placement = Teads.createNativePlacement(pid: pid, settings: adSettings.adPlacementSettings, delegate: self) | ||
placement?.requestAd(requestSettings: adSettings.adRequestSettings) | ||
} | ||
|
||
func handlesUserClicks() -> Bool { | ||
// Let Teads SDK tracks clicks | ||
true | ||
} | ||
|
||
func handlesUserImpressions() -> Bool { | ||
// Let Teads SDK tracks impressions | ||
true | ||
} | ||
|
||
func didRender( | ||
in view: UIView, | ||
clickableAssetViews: [GADNativeAssetIdentifier: UIView], | ||
nonclickableAssetViews _: [GADNativeAssetIdentifier: UIView], | ||
viewController: UIViewController | ||
) { | ||
self.viewController = viewController | ||
nativeAd?.register(containerView: view) | ||
if let adOpportunityView = adOpportunityView { | ||
view.addSubview(adOpportunityView) | ||
self.adOpportunityView = nil | ||
} | ||
clickableAssetViews.forEach { key, assetView in | ||
switch key { | ||
case .headlineAsset: | ||
assetView.bind(component: nativeAd?.title) | ||
case .callToActionAsset: | ||
assetView.bind(component: nativeAd?.callToAction) | ||
case .iconAsset: | ||
assetView.bind(component: nativeAd?.icon) | ||
case .bodyAsset: | ||
assetView.bind(component: nativeAd?.content) | ||
case .priceAsset: | ||
assetView.bind(component: nativeAd?.price) | ||
case .imageAsset: | ||
assetView.bind(component: nativeAd?.image) | ||
case .mediaViewAsset: | ||
assetView.bind(component: nativeAd?.video) | ||
case .starRatingAsset: | ||
assetView.bind(component: nativeAd?.rating) | ||
case .advertiserAsset: | ||
assetView.bind(component: nativeAd?.sponsored) | ||
default: | ||
break | ||
} | ||
} | ||
} | ||
|
||
private func loadNativeImages() { | ||
if let video = nativeAd?.video { | ||
teadsMediaView = TeadsMediaView(videoComponent: video) | ||
if let mediaScale = adSettings?.mediaScale { | ||
teadsMediaView?.mediaScale = mediaScale | ||
} | ||
} | ||
nativeAd?.image?.loadImage(async: false) { [weak self] image in | ||
self?.mappedImages = [GADNativeAdImage(image: image)] | ||
} | ||
|
||
nativeAd?.icon?.loadImage(async: false) { [weak self] image in | ||
self?.mappedIcon = GADNativeAdImage(image: image) | ||
} | ||
} | ||
} | ||
|
||
extension GADMAdapterTeadsNativeAd: TeadsNativeAdPlacementDelegate { | ||
func didReceiveAd(ad: TeadsNativeAd) { | ||
nativeAd = ad | ||
nativeAd?.delegate = self | ||
nativeAd?.playbackDelegate = self | ||
loadNativeImages() | ||
delegate = completionHandler?(self, nil) | ||
completionHandler = nil | ||
placement = nil | ||
adOpportunityView = nil | ||
} | ||
|
||
func didFailToReceiveAd(reason: AdFailReason) { | ||
delegate = completionHandler?(nil, reason) | ||
completionHandler = nil | ||
placement = nil | ||
} | ||
|
||
func adOpportunityTrackerView(trackerView: TeadsAdOpportunityTrackerView) { | ||
adOpportunityView = trackerView | ||
} | ||
} | ||
|
||
extension GADMAdapterTeadsNativeAd: TeadsAdDelegate { | ||
public func didRecordImpression(ad _: TeadsAd) { | ||
delegate?.reportImpression() | ||
} | ||
|
||
public func didRecordClick(ad _: TeadsAd) { | ||
delegate?.reportClick() | ||
} | ||
|
||
public func willPresentModalView(ad _: TeadsAd) -> UIViewController? { | ||
delegate?.willPresentFullScreenView() | ||
return viewController | ||
} | ||
|
||
public func didCatchError(ad _: TeadsAd, error: Error) { | ||
delegate?.didFailToPresentWithError(error) | ||
} | ||
|
||
public func didExpandedToFullscreen(ad _: TeadsAd) { | ||
delegate?.willPresentFullScreenView() | ||
} | ||
|
||
public func didCollapsedFromFullscreen(ad _: TeadsAd) { | ||
delegate?.didDismissFullScreenView() | ||
} | ||
} | ||
|
||
extension GADMAdapterTeadsNativeAd: TeadsPlaybackDelegate { | ||
func didPlay(_: TeadsAd) { | ||
delegate?.didPlayVideo() | ||
} | ||
|
||
func didPause(_: TeadsAd) { | ||
delegate?.didPauseVideo() | ||
} | ||
|
||
func didComplete(_: TeadsAd) { | ||
delegate?.didEndVideo() | ||
} | ||
|
||
func adStartPlayingAudio(_: TeadsAd) { | ||
delegate?.didUnmuteVideo() | ||
} | ||
|
||
func adStopPlayingAudio(_: TeadsAd) { | ||
delegate?.didMuteVideo() | ||
} | ||
} |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// | ||
// TeadsAdapterSettings+GADAdNetworkExtras.swift | ||
// TeadsAdMobAdapter | ||
// | ||
// Created by Thibaud Saint-Etienne on 27/10/2022. | ||
// | ||
|
||
import Foundation | ||
import GoogleMobileAds | ||
import TeadsSDK | ||
|
||
@objc public final class GADMAdapterTeads: NSObject { | ||
@available(*, deprecated, message: "defaultLabel is not used anymore please pass your label value as parameter of the customEventExtra method") | ||
@objc public static let defaultLabel = "Teads" | ||
|
||
/// customEventExtra is a method used to create GADCustomEventExtras based on teadsAdSettings | ||
/// - Parameters: | ||
/// - teadsAdSettings: the TeadsAdapterSettings that you will pass as extra parameters for the mediation. | ||
/// - label: the same label as it registered on your Google dashboard, default value is Teads. | ||
/// | ||
/// - Important: | ||
/// | ||
/// This method is deprecated if favor of registering directly ``TeadsSDK.TeadsAdapterSettings`` | ||
/// ``` | ||
/// import TeadsAdMobAdapter | ||
/// | ||
/// let request = GADRequest() | ||
/// let adSettings = TeadsAdapterSettings { (settings) in | ||
/// settings.pageUrl("http://page.com/article1") | ||
/// settings.registerAdView(admobAdView, delegate: self) | ||
/// } | ||
/// request.register(adSettings) | ||
/// ``` | ||
@available(*, unavailable, message: "customEventExtra is not available anymore, you can register TeadsAdapterSettings directly calling `GADRequest.register(_ )") | ||
@objc public class func customEventExtra(with teadsAdSettings: TeadsAdapterSettings, for label: String) -> GADCustomEventExtras { | ||
let customEventExtras = GADCustomEventExtras() | ||
if let parameters = try? teadsAdSettings.toDictionary() { | ||
customEventExtras.setExtras(parameters, forLabel: label) | ||
} | ||
return customEventExtras | ||
} | ||
} | ||
|
||
extension TeadsAdapterSettings: GADAdNetworkExtras {} |