SDK8 AdMob Mediation Native

出自TAMedia
於 2022年2月14日 (一) 02:37 由 imported>Wikiuser 所做的修訂 →‎已知問題
跳至導覽 跳至搜尋

簡介

將說明如何將 TAmedia SDK 原生廣告與 Google AdMob 原生廣告(Native advanced)做 mediation 整合,關於 AdMob mediation 請參考:https://developers.google.com/admob/ios/mediate

串接準備

開始串接前請間確定已將 TAmedia SDK 整合至專案,並且完成初始化 SDK步驟,若您尚未完成請先參考開始使用教學完成相關設定。
確認已成功串接 AdMob 原生廣告,若還沒請參考 Google 教學AdMob原生廣告教學。新增自訂義事件請參考Google 說明
最後,在專案中加入與 Custom Event 對應的 Class,其中 Custom Event 的 Class Name 需要和專案新增的 Class Name 保持一致,例如新增的 Class Name 為 TADCustomNative,Custom Event 的 Class Name 則必須是 專案名稱.TADCustomNative。(以 Swift 編寫的專案需加上專案名稱;若為以 OC編寫,則放入 Class Name)

整合方式

整合 AdMob 原生廣告需要兩個客製化 class,TADCustomNative 及 TADMediatedUnifiedNativeAd,可直接下載加入專案內或參考下方範例

TADCustomNative

AdMob 將透過這支程式來取得 TAmedia 廣告,其中關於 TADNativeAdOptions 及 TADMediaView 的客製化設定,可以自行參考教學文件進行設定,或保持預設值。

import Foundation
import GoogleMobileAds
import TAMediaAdsFramework

class TADCustomNative: NSObject, GADCustomEventNativeAd {
    weak var delegate: GADCustomEventNativeAdDelegate?
    private var nativeAd: TADNativeAd?
    
    override required init() {
        super.init()
    }
    
    deinit {
        print("TADCustomNative deinit")
    }
    
    func request(withParameter serverParameter: String, request: GADCustomEventRequest, adTypes: [Any], options: [Any], rootViewController: UIViewController) {
        loadTADNativeAd(adUnitId: serverParameter)
    }
    
    func handlesUserClicks() -> Bool {
        return true
    }
    
    func handlesUserImpressions() -> Bool {
        return true
    }
}

extension TADCustomNative {
    private func loadTADNativeAd(adUnitId: String) {
        let request = TADRequest()
        request.showLog = true
        let option = TADNativeAdOptions()
        ///參見 http://wiki.tamedia.com.tw/iosDoc/Classes/TADNativeAdOptions.html
//        option.disableImageLoading = true //SDK 將不自動下載圖片 TADMediatedUnifiedNativeAd 內需更改
//        option.mediaPreferImage = false //只會呈現圖片廣告
//        option.startUnmuted = true     //影片廣告會以非靜音方式呈現
//        option.customControlsRequested = true //
//        option.allowAudioSessionControl = false //設為false則需自行設定影音廣告出現時 AVAudioSession 狀態
        nativeAd = TADNativeAd(adUnitId: adUnitId)
        nativeAd?.delegate = self
        nativeAd?.load(request, withOption: option)
    }
}

extension TADCustomNative: TADNativeAdDelegate {
    func nativeAdDidReceive(_ ad: TADNativeAd!) {
        let nativeAdView = TADNativeAdView()
        let mediaView = TADNativeMediaView(frame: .zero)
        mediaView.mediaContent = ad.adContent.mediaContent
        ///參見 http://wiki.tamedia.com.tw/iosDoc/Classes/TADNativeMediaView.html
//        mediaView.setCallToActionVisible(false) //是否顯示 CTA 按鈕
//        mediaView.setCallToActionTextSize(12) //設定 CTA 文字大小
//        mediaView.setVolumeImageSize(24) //設定影音廣告靜音圖片大小
//        mediaView.setVideoCountdownTextSize(17) //設定影音倒數文字大小
        nativeAdView.addSubview(mediaView)
        nativeAdView.mediaView = mediaView
        
        let mapNativeAd = TADMediatedUnifiedNativeAd(tadNativeAd: ad, tadNativeAdView: nativeAdView)
        delegate?.customEventNativeAd(self, didReceive: mapNativeAd)
    }
    
    func nativeAd(_ ad: TADNativeAd!, didFailToReceiveAdWithError error: TADRequestError!) {
        delegate?.customEventNativeAd(self, didFailToLoadWithError: error)
    }
}

TADMediatedUnifiedNativeAd

將取得的 TAmedia 廣告整合後透過 AdMob 提供的介面回傳給 AdMob

import Foundation
import GoogleMobileAds
import TAMediaAdsFramework

class TADMediatedUnifiedNativeAd: NSObject {
    var tadNativeAd: TADNativeAd
    var tadNativeAdView: TADNativeAdView
    var mappedImages = [GADNativeAdImage]()
    var mapIcon: GADNativeAdImage?
    
    init(tadNativeAd: TADNativeAd, tadNativeAdView: TADNativeAdView) {
        self.tadNativeAdView = tadNativeAdView
        self.tadNativeAd = tadNativeAd
        super.init()
        self.tadNativeAd.delegate = self
        self.tadNativeAdView.mediaView?.statusDelegate = self
        guard let mediaContent = tadNativeAd.adContent.mediaContent else {
            return
        }
        if let tadImage = mediaContent.image1200x627?.image {
            let adImage = GADNativeAdImage(image: tadImage)
            tadNativeAdView.mediaView?.setMainImage(image: tadImage)
            mappedImages.append(adImage)
        }
        if let iconImage = tadNativeAd.adContent.iconSquare?.image {
            mapIcon = GADNativeAdImage(image: iconImage)
        }
    }
    
    deinit {
        print("TADMediatedUnifiedNativeAd - TADMediatedUnifiedNativeAd deinit")
    }
}

extension TADMediatedUnifiedNativeAd: TADNativeAdDelegate {
    func nativeAdDidImpression(_ ad: TADNativeAd!) {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidRecordImpression(self)
        print("TADMediatedUnifiedNativeAd - nativeAdDidImpression")
    }
    
    func nativeAdDidClick(_ ad: TADNativeAd!) {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidRecordClick(self)
        print("TADMediatedUnifiedNativeAd - nativeAdDidClick")
    }
}

extension TADMediatedUnifiedNativeAd: TADVideoStatusDelegate {
    func didStartVideo() {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidPlayVideo(self)
    }
    
    func didPlayVideo() {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidPlayVideo(self)
    }
    
    func didPauseVideo() {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidPauseVideo(self)
    }
    
    func didEndVideoPlayback() {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidEndVideoPlayback(self)
    }
    
    func didMuteVideo() {}
    
    func didUnmuteVideo() {}
}

extension TADMediatedUnifiedNativeAd: GADMediatedUnifiedNativeAd {
    var headline: String? {
        return tadNativeAd.adContent.longSubject
    }
    
    var images: [GADNativeAdImage]? {
        return mappedImages
    }
    
    var body: String? {
        return tadNativeAd.adContent.body
    }
    
    var icon: GADNativeAdImage? {
        return mapIcon
    }
    
    var callToAction: String? {
        return tadNativeAd.adContent.callToAction
    }
    
    var starRating: NSDecimalNumber? {
        return nil
    }
    
    var store: String? {
        return nil
    }
    
    var price: String? {
        return nil
    }
    
    var advertiser: String? {
        return nil
    }
    
    var extraAssets: [String: Any]? {
        return nil
    }
    
    var mediaView: UIView? {
        return tadNativeAdView.mediaView
    }
    
    var hasVideoContent: Bool {
        guard let mediaContent = tadNativeAd.adContent.mediaContent else {
            return false
        }
        return mediaContent.isVideoContent
    }
    
    func didRender(in view: UIView, clickableAssetViews: [GADNativeAssetIdentifier: UIView], nonclickableAssetViews: [GADNativeAssetIdentifier: UIView], viewController: UIViewController) {
        view.subviews.first { $0 is TADNativeAdView }?.removeFromSuperview()
        view.insertSubview(tadNativeAdView, at: 0)
        fillSuperView(view: tadNativeAdView)
        
        if let titleLabel = clickableAssetViews[GADNativeAssetIdentifier.headlineAsset] as? UILabel {
            titleLabel.isUserInteractionEnabled = true
            tadNativeAdView.longSubjectLabel = titleLabel
        }

        if let bodyLabel = clickableAssetViews[GADNativeAssetIdentifier.bodyAsset] as? UILabel {
            bodyLabel.isUserInteractionEnabled = true
            tadNativeAdView.bodyLabel = bodyLabel
        }

        if let ctaLabel = clickableAssetViews[GADNativeAssetIdentifier.callToActionAsset] {
            ctaLabel.isUserInteractionEnabled = true
            tadNativeAdView.callToActionView = ctaLabel
        }
        
        if let icon = clickableAssetViews[GADNativeAssetIdentifier.iconAsset] as? UIImageView {
            icon.isUserInteractionEnabled = true
            tadNativeAdView.squareImgeView = icon
        }

        if let mediaView = clickableAssetViews[GADNativeAssetIdentifier.mediaViewAsset], let tadMediaView = tadNativeAdView.mediaView {
            mediaView.subviews.first { $0 is TADNativeMediaView }?.removeFromSuperview()
            mediaView.addSubview(tadMediaView)
            fillSuperView(view: tadMediaView)
        }
        
        tadNativeAdView.nativeAd = tadNativeAd
    }
    
    func didUntrackView(_ view: UIView?) {
        print("TADMediatedUnifiedNativeAd - didUntrackView")
        tadNativeAdView.removeFromSuperview()
        tadNativeAdView.mediaView?.removeFromSuperview()
    }
}

extension TADMediatedUnifiedNativeAd {
    func fillSuperView(view: UIView) {
        view.frame = view.superview?.bounds ?? .zero
    }
}

已知問題

目前點擊及曝光的事件當 TAmedia 廣告觸發後並沒有觸發 GADNativeAdDelegate 內 nativeAdDidRecordClick 及 nativeAdDidRecordImpression,目前推測為 Google SDK 的問題,若需要做相關紀錄須在 TADMediatedUnifiedNativeAd 內自行加入。

extension TADMediatedUnifiedNativeAd: TADNativeAdDelegate {
    func nativeAdDidImpression(_ ad: TADNativeAd!) {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidRecordImpression(self)
        print("TADMediatedUnifiedNativeAd - nativeAdDidImpression")
        /// 若需要紀錄曝光事件請在此自行加入
    }
    
    func nativeAdDidClick(_ ad: TADNativeAd!) {
        GADMediatedUnifiedNativeAdNotificationSource.mediatedNativeAdDidRecordClick(self)
        print("TADMediatedUnifiedNativeAd - nativeAdDidClick")
        /// 若需要紀錄點擊事件請在此自行加入
    }
}

回 SDK 8首頁