Skip to content

Commit

Permalink
Release 7.6.0
Browse files Browse the repository at this point in the history
  • Loading branch information
mobile-ads-github committed Oct 17, 2024
1 parent e33da2f commit 88c1595
Show file tree
Hide file tree
Showing 32 changed files with 574 additions and 34 deletions.
5 changes: 4 additions & 1 deletion Examples/ThirdPartyMediationAdapterTemplate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ This way you will get a separate adapter class for each of the ad formats. If yo

* `Interstitial`, `Rewarded`, `AppOpen` formats provide loader classes. A loader object can be [created](./ThirdPartyMediationAdapterTemplate/AdapterTemplate/YandexAdapters.swift#L165) once and can be reused. This speeds up loading and can be helpful to implement preloading logic, if your network supports it.

* `Native` format includes both the required and optional [assets](https://yandex.ru/support2/mobile-ads/en/dev/ios/components). The way to provide custom assets for binding strongly depends on the API of your ads SDK. The [template]((./ThirdPartyMediationAdapterTemplate/AdapterTemplate/YandexAdapters.swift#L503)) shows how these assets are passed to adapter during the ad request by providing a map of `string identifier` to `asset view identifier` on the publisher side.

### 4. Test integration

It is recommended to use test ads to check your adapter. These special demo ad unit identifiers guarantee successful ad response for each request:
Expand All @@ -46,6 +48,7 @@ It is recommended to use test ads to check your adapter. These special demo ad u
* Banner format: `demo-banner-yandex`
* Interstitial format: `demo-interstitial-yandex`
* Rewarded format: `demo-rewarded-yandex`
* Native format: `demo-native-content-yandex`, `demo-native-app-yandex`, `demo-native-video-yandex`

## Additional info

Expand Down Expand Up @@ -77,7 +80,7 @@ See also: [GDPR](https://ads.yandex.com/helpcenter/en/dev/ios/gdpr).
As shown in the [template](./ThirdPartyMediationAdapterTemplate/AdapterTemplate/YandexAdapters.swift#L42), the bidder token can be obtained as follows:

```swift
let bidderTokenLoader = BidderTokenLoader()
let bidderTokenLoader = BidderTokenLoader(mediationNetworkName: "MEDIATION_NETWORK_NAME")
bidderTokenLoader.loadBidderToken(requestConfiguration: requestConfiguraton) { token in
completion(token)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 7.5.1;
CURRENT_PROJECT_VERSION = 7.6.0;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
Expand All @@ -305,7 +305,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 7.5.1;
MARKETING_VERSION = 7.6.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
Expand Down Expand Up @@ -349,7 +349,7 @@
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 7.5.1;
CURRENT_PROJECT_VERSION = 7.6.0;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
Expand All @@ -364,7 +364,7 @@
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
MARKETING_VERSION = 7.5.1;
MARKETING_VERSION = 7.6.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum MediationAdFormat {
case interstitial
case rewarded
case appOpen
case native
}

/// List of adUnits for checking inegration with Yandex.
Expand All @@ -52,6 +53,7 @@ enum DemoAdUnit: String {
case demoInterstititalAdUinitId = "demo-interstitital-yandex"
case demoRewardedAdUnitId = "demo-rewarded-yandex"
case demoAppOpenAdUnitId = "demo-appopenad-yandex"
case demoNativeAdUnitId = "demo-native-content-yandex"
}

//MARK: - Initialization API
Expand Down Expand Up @@ -267,3 +269,145 @@ protocol MediationAppOpenDelegate: AnyObject {
/// Notifies when an impression was tracked.
func appOpenDidTrackImpression()
}

//MARK: - Native API

/// This protocol describes methods for native ads.
protocol MediationNative {
/// Loads nativeAd
/// - Parameters:
/// - adData: Object that contains parameters for nativeAd request.
/// - delegate: Delegate that implements your ad network native callbacks.
/// - parameters: Additional parameters for ads request configuration.
func loadAd(with adData: AdData,
delegate: MediationNativeDelegate,
parameters: AdapterParameters)

/// The API of some ad networks require a destroy method.
/// This method is called when an ad associated with this adapter should be destroyed. Necessary cleanup should be performed here.
func destroy()
}

/// This protocol describes your ad network native callbacks.
protocol MediationNativeDelegate: AnyObject {
/// Notifies that the native is loaded.
func nativeDidLoad(ad: MediationNativeAd)

/// Notifies that the native is failed to load.
func nativeDidFailToLoad(with error: Error)

/// Notifies that the native ad is failed to bind.
func nativeDidFailToBind(with error: Error)

/// Notifies that the ad will show the modal `UIViewController` in response to the user interacting with the banner.
func nativeWillPresentScreen()

/// Notifies that the ad finished showing the modal `UIViewController` in response to the user interacting with the banner.
func nativeDidDismissScreen()

/// Called after native the rewarded ad.
func nativeDidDismiss()

/// Notifies that the user has clicked on the native.
func nativeDidClick()

/// Notifies when an impression was tracked.
func nativeDidTrackImpression()
}

/// This protocol describes a native ad object that the ad network SDK expects after it is loaded.
/// The adapter will extend and bind this class after successful ad loading.
/// In the real case this logic is strongly depends on the ad network SDK and should be changed to match it.
protocol MediationNativeAd {
/// Age restrictions.
var age: String? { get set }

/// The main ad text.
var body: String? { get set }

/// The call to action.
var callToAction: String? { get set }

/// The domain.
var domain: String? { get set }

/// The web page's favicon.
var favicon: UIImage? { get set }

/// The app's icon.
var icon: UIImage? { get set }

/// The main image.
var image: UIImage? { get set }

/// Ad media.
var media: UIView? { get set }

/// The price of the advertised app.
var price: String? { get set }

/// The app's rating.
var rating: NSNumber? { get set }

/// The number of app reviews.
var reviewCount: String? { get set }

/// Data on the ad network.
var sponsored: String? { get set }

/// The ad title.
var title: String? { get set }

/// The warning.
var warning: String? { get set }

/// Method for properly binding views in native ad format.
func trackViews(adNetworkView: MediationNativeAdView)
}

/// This protocol describes a native ad view of the ad network which will be used to obtain ad assets.
/// Ad network required views and Yandex required views may mismatch. Check docs to resolve it.
/// https://yandex.ru/support2/mobile-ads/en/dev/ios/components
protocol MediationNativeAdView: UIView {
/// `UILabel` for information about age restrictions.
var ageLabel: UILabel? { get }

/// `UILabel` for the main ad text.
var bodyLabel: UILabel? { get }

/// `UIButton` with a call to action.
var callToActionButton: UIButton? { get }

/// `UILabel` for domain data.
var domainLabel: UILabel? { get }

/// `UIImageView` for the favicon.
var faviconImageView: UIImageView? { get }

/// `UIButton` for handling reasons for ad closing.
var feedbackButton: UIButton? { get }

/// `UIImageView` for the icon.
var iconImageView: UIImageView? { get }

/// `UIView` for the ad's media.
var mediaView: UIView? { get }

/// `UILabel` for data on the price of the advertised app.
var priceLabel: UILabel? { get }

/// `UIView` for data on the app rating.
var ratingView: UIView? { get }

/// `UILabel` for data on the number of app reviews.
var reviewCountLabel: UILabel? { get }

/// `UILabel` for information about the ad network.
var sponsoredLabel: UILabel? { get }

/// `UILabel` for the ad title.
var titleLabel: UILabel? { get }

/// `UILabel` for the warning.
var warningLabel: UILabel? { get }
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ private let mockPresentingError = AdapterError(errorDescription: "Ad Display Fai

/// This class implements base methods for all other adapters.
class YandexBaseAdapter: NSObject, MediationBidding, MediationInitialization {
private static let bidderTokenLoader = BidderTokenLoader()
private static let bidderTokenLoader = BidderTokenLoader(mediationNetworkName: "MEDIATION_NETWORK_NAME")

/// This method implements obtaining a bid token in order to use it with in-app bidding integration with Yandex.
/// https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/ru/jazzy/Classes/BidderTokenLoader.html
Expand All @@ -35,6 +35,8 @@ class YandexBaseAdapter: NSObject, MediationBidding, MediationInitialization {
requestConfiguraton = BidderTokenRequestConfiguration(adType: .rewarded)
case .appOpen:
requestConfiguraton = BidderTokenRequestConfiguration(adType: .appOpenAd)
case .native:
requestConfiguraton = BidderTokenRequestConfiguration(adType: .native)
}

requestConfiguraton.parameters = Self.makeConfigurationParameters(parameters)
Expand Down Expand Up @@ -89,6 +91,20 @@ class YandexBaseAdapter: NSObject, MediationBidding, MediationInitialization {

return configuration
}

/// This method implements creation of `NativeAdRequestConfiguration` with all the necessary parameters.
func makeNativeAdRequestConfiguration(with adData: AdData, parameters: AdapterParameters) -> NativeAdRequestConfiguration {
let configuration = MutableNativeAdRequestConfiguration(adUnitID: adData.adUinitId)
let configParameters = Self.makeConfigurationParameters(parameters)

configuration.parameters = configParameters

if let biddingData = adData.bidId {
configuration.biddingData = biddingData
}

return configuration
}
}

//MARK: - Banner Adapter
Expand Down Expand Up @@ -388,3 +404,136 @@ extension YandexAppOpenAdapter: AppOpenAdLoaderDelegate {
delegate?.appOpenDidFailToLoad(with: error.error)
}
}

//MARK: - Native Adapter

/// This class implements base methods for native adapter.
final class YandexNativeAdapter: YandexBaseAdapter, MediationNative {
private weak var delegate: MediationNativeDelegate?
private lazy var loader: NativeAdLoader = {
let loader = NativeAdLoader()
loader.delegate = self
return loader
}()
private var nativeAd: NativeAd?

func loadAd(with adData: AdData,
delegate: MediationNativeDelegate,
parameters: AdapterParameters) {
self.delegate = delegate
let configuration = makeNativeAdRequestConfiguration(with: adData, parameters: parameters)
Self.setupYandexSDK(with: parameters)
loader.loadAd(with: configuration)
}

func destroy() {
nativeAd?.delegate = nil
nativeAd = nil
}
}

/// `NativeAdDelegate` implementation.
/// https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/ru/jazzy/Protocols/NativeAdDelegate.html
extension YandexNativeAdapter: NativeAdDelegate {
func nativeAdDidClick(_ ad: NativeAd) {
delegate?.nativeDidClick()
}

func nativeAd(_ ad: NativeAd, didTrackImpressionWith impressionData: ImpressionData?) {
delegate?.nativeDidTrackImpression()
}

func nativeAd(_ ad: NativeAd, didDismissScreen viewController: UIViewController?) {
delegate?.nativeDidDismissScreen()
}

func nativeAd(_ ad: any NativeAd, willPresentScreen viewController: UIViewController?) {
delegate?.nativeWillPresentScreen()
}

func close(_ ad: NativeAd) {
delegate?.nativeDidDismiss()
}
}

/// `NativeAdLoaderDelegate` implementation.
/// https://yastatic.net/s3/doc-binary/src/dev/mobile-ads/ru/jazzy/Protocols/NativeAdLoaderDelegate.html
extension YandexNativeAdapter: NativeAdLoaderDelegate {
func nativeAdLoader(_ loader: NativeAdLoader, didLoad ad: NativeAd) {
ad.delegate = self
nativeAd = ad
let assets = ad.adAssets()

let mediationNativeAd = YandexNativeAd(nativeAd: ad)
mediationNativeAd.delegate = delegate
mediationNativeAd.age = assets.age
mediationNativeAd.body = assets.body
mediationNativeAd.callToAction = assets.callToAction
mediationNativeAd.domain = assets.domain
mediationNativeAd.favicon = assets.favicon?.imageValue
mediationNativeAd.icon = assets.icon?.imageValue
mediationNativeAd.image = assets.image?.imageValue
mediationNativeAd.media = YMANativeMediaView()
mediationNativeAd.price = assets.price
mediationNativeAd.rating = assets.rating
mediationNativeAd.reviewCount = assets.reviewCount
mediationNativeAd.sponsored = assets.sponsored
mediationNativeAd.title = assets.title
mediationNativeAd.warning = assets.warning

delegate?.nativeDidLoad(ad: mediationNativeAd)
}

func nativeAdLoader(_ loader: NativeAdLoader, didFailLoadingWithError error: Error) {
delegate?.nativeDidFailToLoad(with: error)
}
}

/// This class implements a native ad object that the ad network SDK expects after it is loaded.
final class YandexNativeAd: MediationNativeAd {
weak var delegate: MediationNativeDelegate?
let nativeAd: NativeAd

init(nativeAd: NativeAd) {
self.nativeAd = nativeAd
}

/// Method for properly binding views in native ad format.
/// In the real case this logic is strongly depends on the ad network SDK and should be changed to match it.
func trackViews(adNetworkView: MediationNativeAdView) {
let viewData = NativeAdViewData()
viewData.ageLabel = adNetworkView.ageLabel
viewData.bodyLabel = adNetworkView.bodyLabel
viewData.callToActionButton = adNetworkView.callToActionButton
viewData.domainLabel = adNetworkView.domainLabel
viewData.faviconImageView = adNetworkView.faviconImageView
viewData.iconImageView = adNetworkView.iconImageView
viewData.mediaView = adNetworkView.mediaView as? YMANativeMediaView
viewData.priceLabel = adNetworkView.priceLabel
viewData.ratingView = adNetworkView.priceLabel as? (UIView & Rating)
viewData.reviewCountLabel = adNetworkView.reviewCountLabel
viewData.sponsoredLabel = adNetworkView.sponsoredLabel
viewData.titleLabel = adNetworkView.titleLabel
viewData.warningLabel = adNetworkView.warningLabel
do {
try nativeAd.bindAd(to: adNetworkView, viewData: viewData)
} catch {
delegate?.nativeDidFailToBind(with: error)
}
}

var age: String?
var body: String?
var callToAction: String?
var domain: String?
var favicon: UIImage?
var icon: UIImage?
var image: UIImage?
var media: UIView?
var price: String?
var rating: NSNumber?
var reviewCount: String?
var sponsored: String?
var title: String?
var warning: String?
}
Loading

0 comments on commit 88c1595

Please sign in to comment.