Điều kiện tiên quyết
Hoàn tất quy trình thiết lập sự kiện tuỳ chỉnh.
Yêu cầu hiển thị quảng cáo gốc
Khi đạt đến mục hàng sự kiện tuỳ chỉnh trong chuỗi dàn xếp kiểu thác nước, phương thức loadNativeAd:adConfiguration:completionHandler:
sẽ được gọi theo tên lớp mà bạn đã cung cấp khi tạo một sự kiện tuỳ chỉnh. Trong trường hợp này, phương thức đó nằm trong SampleCustomEvent
, sau đó gọi phương thức loadNativeAd:adConfiguration:completionHandler:
trong SampleCustomEventNative
.
Để yêu cầu hiển thị một quảng cáo gốc, hãy tạo hoặc sửa đổi một lớp triển khai GADMediationAdapter
và loadNativeAd:adConfiguration:completionHandler:
. Nếu đã có một lớp mở rộng GADMediationAdapter
, hãy triển khai loadNativeAd:adConfiguration:completionHandler:
ở đó. Ngoài ra, hãy tạo một lớp mới để triển khai GADMediationNativeAd
.
Trong ví dụ về sự kiện tuỳ chỉnh của chúng tôi, SampleCustomEvent
sẽ triển khai giao diện GADMediationAdapter
và sau đó uỷ quyền cho SampleCustomEventNative
.
Swift
import GoogleMobileAds class SampleCustomEvent: NSObject, GADMediationAdapter { fileprivate var nativeAd: SampleCustomEventNativeAd? func loadNativeAd( for adConfiguration: GADMediationNativeAdConfiguration, completionHandler: @escaping GADMediationNativeAdLoadCompletionHandler ) { self.nativeAd = SampleCustomEventNativeAd() self.nativeAd?.loadNativeAd( for: adConfiguration, completionHandler: completionHandler) } }
Objective-C
#import "SampleCustomEvent.h" @implementation SampleCustomEvent SampleCustomEventNativeAd *sampleNativeAd; - (void)loadNativeAdForAdConfiguration: (GADMediationNativeAdConfiguration *)adConfiguration completionHandler: (GADMediationNativeAdLoadCompletionHandler) completionHandler { sampleNative = [[SampleCustomEventNativeAd alloc] init]; [sampleNative loadNativeAdForAdConfiguration:adConfiguration completionHandler:completionHandler]; }
SampleCustomEventNative` chịu trách nhiệm thực hiện những việc sau:
Tải quảng cáo gốc
Triển khai giao thức
GADMediationNativeAd
.Nhận và báo cáo lệnh gọi lại sự kiện quảng cáo cho SDK quảng cáo trên thiết bị di động của Google
Thông số không bắt buộc được xác định trong giao diện người dùng Ad Manager sẽ được đưa vào cấu hình quảng cáo.
Bạn có thể truy cập vào thông số này qua adConfiguration.credentials.settings[@"parameter"]
. Thông số này thường là giá trị nhận dạng đơn vị quảng cáo mà SDK mạng quảng cáo cần có khi tạo bản sao cho một đối tượng quảng cáo.
Swift
class SampleCustomEventNativeAd: NSObject, GADMediationNativeAd { /// The Sample Ad Network native ad. var nativeAd: SampleNativeAd? /// 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? func loadNativeAd( for adConfiguration: GADMediationNativeAdConfiguration, completionHandler: @escaping GADMediationNativeLoadCompletionHandler ) { let adLoader = SampleNativeAdLoader() let sampleRequest = SampleNativeAdRequest() // The Google Mobile Ads SDK requires the image assets to be downloaded // automatically unless the publisher specifies otherwise by using the // GADNativeAdImageAdLoaderOptions object's disableImageLoading property. If // your network doesn't have an option like this and instead only ever // returns URLs for images (rather than the images themselves), your adapter // should download image assets on behalf of the publisher. This should be // done after receiving the native ad object from your network's SDK, and // before calling the connector's adapter:didReceiveMediatedNativeAd: method. sampleRequest.shouldDownloadImages = true sampleRequest.preferredImageOrientation = NativeAdImageOrientation.any sampleRequest.shouldRequestMultipleImages = false let options = adConfiguration.options for loaderOptions: GADAdLoaderOptions in options { if let imageOptions = loaderOptions as? GADNativeAdImageAdLoaderOptions { sampleRequest.shouldRequestMultipleImages = imageOptions.shouldRequestMultipleImages // If the GADNativeAdImageAdLoaderOptions' disableImageLoading property is // YES, the adapter should send just the URLs for the images. sampleRequest.shouldDownloadImages = !imageOptions.disableImageLoading } else if let mediaOptions = loaderOptions as? GADNativeAdMediaAdLoaderOptions { switch mediaOptions.mediaAspectRatio { case GADMediaAspectRatio.landscape: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.landscape case GADMediaAspectRatio.portrait: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.portrait default: sampleRequest.preferredImageOrientation = NativeAdImageOrientation.any } } } // This custom event uses the server parameter to carry an ad unit ID, which // is the most common use case. adLoader.delegate = self adLoader.adUnitID = adConfiguration.credentials.settings["parameter"] as? String self.completionHandler = completionHandler adLoader.fetchAd(sampleRequest) } }
Objective-C
#import "SampleCustomEventNativeAd.h" @interface SampleCustomEventNativeAd () <SampleNativeAdDelegate, GADMediationNativeAd> { /// The sample native ad. SampleNativeAd *_nativeAd; /// The completion handler to call when the ad loading succeeds or fails. GADMediationNativeLoadCompletionHandler _loadCompletionHandler; /// The ad event delegate to forward ad rendering events to the Google Mobile /// Ads SDK. id<GADMediationNativeAdEventDelegate> _adEventDelegate; } @end - (void)loadNativeAdForAdConfiguration: (GADMediationNativeAdConfiguration *)adConfiguration completionHandler:(GADMediationNativeLoadCompletionHandler) completionHandler { __block atomic_flag completionHandlerCalled = ATOMIC_FLAG_INIT; __block GADMediationNativeLoadCompletionHandler originalCompletionHandler = [completionHandler copy]; _loadCompletionHandler = ^id<GADMediationNativeAdEventDelegate>( _Nullable id<GADMediationNativeAd> ad, NSError *_Nullable error) { // Only allow completion handler to be called once. if (atomic_flag_test_and_set(&completionHandlerCalled)) { return nil; } id<GADMediationNativeAdEventDelegate> delegate = nil; if (originalCompletionHandler) { // Call original handler and hold on to its return value. delegate = originalCompletionHandler(ad, error); } // Release reference to handler. Objects retained by the handler will also // be released. originalCompletionHandler = nil; return delegate; }; SampleNativeAdLoader *adLoader = [[SampleNativeAdLoader alloc] init]; SampleNativeAdRequest *sampleRequest = [[SampleNativeAdRequest alloc] init]; // The Google Mobile Ads SDK requires the image assets to be downloaded // automatically unless the publisher specifies otherwise by using the // GADNativeAdImageAdLoaderOptions object's disableImageLoading property. If // your network doesn't have an option like this and instead only ever returns // URLs for images (rather than the images themselves), your adapter should // download image assets on behalf of the publisher. This should be done after // receiving the native ad object from your network's SDK, and before calling // the connector's adapter:didReceiveMediatedNativeAd: method. sampleRequest.shouldDownloadImages = YES; sampleRequest.preferredImageOrientation = NativeAdImageOrientationAny; sampleRequest.shouldRequestMultipleImages = NO; sampleRequest.testMode = adConfiguration.isTestRequest; for (GADAdLoaderOptions *loaderOptions in adConfiguration.options) { if ([loaderOptions isKindOfClass:[GADNativeAdImageAdLoaderOptions class]]) { GADNativeAdImageAdLoaderOptions *imageOptions = (GADNativeAdImageAdLoaderOptions *)loaderOptions; sampleRequest.shouldRequestMultipleImages = imageOptions.shouldRequestMultipleImages; // If the GADNativeAdImageAdLoaderOptions' disableImageLoading property is // YES, the adapter should send just the URLs for the images. sampleRequest.shouldDownloadImages = !imageOptions.disableImageLoading; } else if ([loaderOptions isKindOfClass:[GADNativeAdMediaAdLoaderOptions class]]) { GADNativeAdMediaAdLoaderOptions *mediaOptions = (GADNativeAdMediaAdLoaderOptions *)loaderOptions; switch (mediaOptions.mediaAspectRatio) { case GADMediaAspectRatioLandscape: sampleRequest.preferredImageOrientation = NativeAdImageOrientationLandscape; break; case GADMediaAspectRatioPortrait: sampleRequest.preferredImageOrientation = NativeAdImageOrientationPortrait; break; default: sampleRequest.preferredImageOrientation = NativeAdImageOrientationAny; break; } } else if ([loaderOptions isKindOfClass:[GADNativeAdViewAdOptions class]]) { _nativeAdViewAdOptions = (GADNativeAdViewAdOptions *)loaderOptions; } } // This custom event uses the server parameter to carry an ad unit ID, which // is the most common use case. NSString *adUnit = adConfiguration.credentials.settings[@"parameter"]; adLoader.adUnitID = adUnit; adLoader.delegate = self; [adLoader fetchAd:sampleRequest]; }
Dù quảng cáo được tìm nạp thành công hay gặp lỗi, bạn vẫn sẽ gọi GADMediationNativeAdLoadCompletionHandler
. Nếu quảng cáo được tìm nạp thành công, hãy truyền qua lớp triển khai GADMediationNativeAd
với giá trị nil
cho thông số lỗi; nếu không thành công, hãy truyền qua lỗi mà bạn gặp phải.
Thông thường, các phương thức này được triển khai bên trong lệnh gọi lại từ SDK bên thứ ba mà bộ chuyển đổi của bạn triển khai. Trong ví dụ này, SDK mẫu có một SampleNativeAdDelegate
với các lệnh gọi lại phù hợp:
Swift
func adLoader( _ adLoader: SampleNativeAdLoader, didReceive nativeAd: SampleNativeAd ) { extraAssets = [ SampleCustomEventConstantsSwift.awesomenessKey: nativeAd.degreeOfAwesomeness ?? "" ] if let image = nativeAd.image { images = [GADNativeAdImage(image: image)] } else { let imageUrl = URL(fileURLWithPath: nativeAd.imageURL) images = [GADNativeAdImage(url: imageUrl, scale: nativeAd.imageScale)] } if let mappedIcon = nativeAd.icon { icon = GADNativeAdImage(image: mappedIcon) } else { let iconURL = URL(fileURLWithPath: nativeAd.iconURL) icon = GADNativeAdImage(url: iconURL, scale: nativeAd.iconScale) } adChoicesView = SampleAdInfoView() self.nativeAd = nativeAd if let handler = completionHandler { delegate = handler(self, nil) } } func adLoader( _ adLoader: SampleNativeAdLoader, didFailToLoadAdWith errorCode: SampleErrorCode ) { let error = SampleCustomEventUtilsSwift.SampleCustomEventErrorWithCodeAndDescription( code: SampleCustomEventErrorCodeSwift .SampleCustomEventErrorAdLoadFailureCallback, description: "Sample SDK returned an ad load failure callback with error code: \(errorCode)" ) if let handler = completionHandler { delegate = handler(nil, error) } }
Objective-C
- (void)adLoader:(SampleNativeAdLoader *)adLoader didReceiveNativeAd:(SampleNativeAd *)nativeAd { if (nativeAd.image) { _images = @[ [[GADNativeAdImage alloc] initWithImage:nativeAd.image] ]; } else { NSURL *imageURL = [[NSURL alloc] initFileURLWithPath:nativeAd.imageURL]; _images = @[ [[GADNativeAdImage alloc] initWithURL:imageURL scale:nativeAd.imageScale] ]; } if (nativeAd.icon) { _icon = [[GADNativeAdImage alloc] initWithImage:nativeAd.icon]; } else { NSURL *iconURL = [[NSURL alloc] initFileURLWithPath:nativeAd.iconURL]; _icon = [[GADNativeAdImage alloc] initWithURL:iconURL scale:nativeAd.iconScale]; } // The sample SDK provides an AdChoices view (SampleAdInfoView). If your SDK // provides image and click through URLs for its AdChoices icon instead of an // actual UIView, the adapter is responsible for downloading the icon image // and creating the AdChoices icon view. _adChoicesView = [[SampleAdInfoView alloc] init]; _nativeAd = nativeAd; _adEventDelegate = _loadCompletionHandler(self, nil); } - (void)adLoader:(SampleNativeAdLoader *)adLoader didFailToLoadAdWithErrorCode:(SampleErrorCode)errorCode { NSError *error = SampleCustomEventErrorWithCodeAndDescription( SampleCustomEventErrorAdLoadFailureCallback, [NSString stringWithFormat:@"Sample SDK returned an ad load failure " @"callback with error code: %@", errorCode]); _adEventDelegate = _loadCompletionHandler(nil, error); }
Liên kết quảng cáo gốc
Các SDK khác nhau đều có định dạng riêng cho quảng cáo gốc. Ví dụ: một SDK có thể trả về các đối tượng chứa trường "tiêu đề" trong khi một SDK khác có thể có trường "dòng tiêu đề". Ngoài ra, các phương thức dùng để theo dõi lượt hiển thị và xử lý lượt nhấp có thể khác nhau giữa các SDK.
Để giải quyết các vấn đề này, khi nhận được đối tượng quảng cáo gốc từ SDK đã dàn xếp, sự kiện tuỳ chỉnh phải sử dụng một lớp triển khai GADMediationNativeAd
, như SampleCustomEventNativeAd
, để "liên kết" các đối tượng quảng cáo gốc của SDK đã dàn xếp cho phù hợp với giao diện mà SDK quảng cáo trên thiết bị di động của Google yêu cầu.
Bây giờ, chúng ta sẽ xem xét kỹ hơn thông tin chi tiết về cách triển khai cho SampleCustomEventNativeAd
.
Lưu trữ các mối liên kết
Theo dự kiến, GADMediationNativeAd
sẽ triển khai một số thuộc tính nhất định được liên kết từ các thuộc tính của SDK khác:
Swift
var nativeAd: SampleNativeAd? var headline: String? { return nativeAd?.headline } var images: [GADNativeAdImage]? var body: String? { return nativeAd?.body } var icon: GADNativeAdImage? var callToAction: String? { return nativeAd?.callToAction } var starRating: NSDecimalNumber? { return nativeAd?.starRating } var store: String? { return nativeAd?.store } var price: String? { return nativeAd?.price } var advertiser: String? { return nativeAd?.advertiser } var extraAssets: [String: Any]? { return [ SampleCustomEventConstantsSwift.awesomenessKey: nativeAd?.degreeOfAwesomeness ?? "" ] } var adChoicesView: UIView? var mediaView: UIView? { return nativeAd?.mediaView }
Objective-C
/// Used to store the ad's images. In order to implement the /// GADMediationNativeAd protocol, we use this class to return the images /// property. NSArray<GADNativeAdImage *> *_images; /// Used to store the ad's icon. In order to implement the GADMediationNativeAd /// protocol, we use this class to return the icon property. GADNativeAdImage *_icon; /// Used to store the ad's ad choices view. In order to implement the /// GADMediationNativeAd protocol, we use this class to return the adChoicesView /// property. UIView *_adChoicesView; - (nullable NSString *)headline { return _nativeAd.headline; } - (nullable NSArray<GADNativeAdImage *> *)images { return _images; } - (nullable NSString *)body { return _nativeAd.body; } - (nullable GADNativeAdImage *)icon { return _icon; } - (nullable NSString *)callToAction { return _nativeAd.callToAction; } - (nullable NSDecimalNumber *)starRating { return _nativeAd.starRating; } - (nullable NSString *)store { return _nativeAd.store; } - (nullable NSString *)price { return _nativeAd.price; } - (nullable NSString *)advertiser { return _nativeAd.advertiser; } - (nullable NSDictionary<NSString *, id> *)extraAssets { return @{SampleCustomEventExtraKeyAwesomeness : _nativeAd.degreeOfAwesomeness}; } - (nullable UIView *)adChoicesView { return _adChoicesView; } - (nullable UIView *)mediaView { return _nativeAd.mediaView; } - (BOOL)hasVideoContent { return self.mediaView != nil; }
Một số mạng đã dàn xếp có thể cung cấp thêm thành phần khác ngoài những thành phần do SDK quảng cáo trên thiết bị di động của Google xác định. Giao thức GADMediationNativeAd
bao gồm một phương thức có tên là extraAssets
. SDK quảng cáo trên thiết bị di động của Google sử dụng phương thức này để truy xuất mọi thành phần "bổ sung" từ trình liên kết.
Liên kết thành phần hình ảnh
Việc liên kết thành phần hình ảnh phức tạp hơn so với việc liên kết các loại dữ liệu đơn giản hơn (như NSString
hoặc double
). Hình ảnh có thể được tải xuống tự động hoặc được trả về dưới dạng giá trị URL. Mật độ pixel cũng có thể thay đổi.
Để giúp bạn quản lý các thông tin chi tiết này, SDK quảng cáo trên thiết bị di động của Google cung cấp lớp GADNativeAdImage
. Thông tin về thành phần hình ảnh (cho dù là đối tượng UIImage
thực tế hay chỉ là các giá trị NSURL
) phải được trả về SDK quảng cáo trên thiết bị di động của Google bằng cách sử dụng lớp này.
Dưới đây là cách lớp trình liên kết xử lý việc tạo GADNativeAdImage
để giữ hình ảnh biểu tượng:
Swift
if let image = nativeAd.image { images = [GADNativeAdImage(image: image)] } else { let imageUrl = URL(fileURLWithPath: nativeAd.imageURL) images = [GADNativeAdImage(url: imageUrl, scale: nativeAd.imageScale)] }
Objective-C
if (nativeAd.image) { _images = @[ [[GADNativeAdImage alloc] initWithImage:nativeAd.image] ]; } else { NSURL *imageURL = [[NSURL alloc] initFileURLWithPath:nativeAd.imageURL]; _images = @[ [[GADNativeAdImage alloc] initWithURL:imageURL scale:nativeAd.imageScale] ]; }
Sự kiện lượt hiển thị và sự kiện nhấp chuột
Cả SDK quảng cáo trên thiết bị di động của Google và SDK đã dàn xếp đều cần phải biết thời điểm xảy ra lượt hiển thị hoặc lượt nhấp, nhưng chỉ cần một SDK theo dõi các sự kiện này. Các sự kiện tuỳ chỉnh có thể sử dụng 2 phương pháp tiếp cận khác nhau, tuỳ thuộc vào việc SDK đã dàn xếp có hỗ trợ tính năng theo dõi lượt hiển thị và lượt nhấp hay không.
Theo dõi lượt nhấp và lượt hiển thị bằng SDK quảng cáo trên thiết bị di động của Google
Nếu SDK đã dàn xếp không theo dõi lượt hiển thị và lượt nhấp nhưng có cung cấp các phương thức để ghi lại lượt nhấp và lượt hiển thị, thì SDK quảng cáo trên thiết bị di động của Google có thể theo dõi các sự kiện này và thông báo cho bộ chuyển đổi. Giao thức GADMediationNativeAd
bao gồm hai phương thức: didRecordImpression:
và didRecordClickOnAssetWithName:view:viewController:
. Các sự kiện tuỳ chỉnh có thể triển khai hai phương thức này để gọi phương thức tương ứng trên đối tượng quảng cáo gốc đã dàn xếp:
Swift
func didRecordImpression() { nativeAd?.recordImpression() } func didRecordClickOnAsset( withName assetName: GADUnifiedNativeAssetIdentifier, view: UIView, wController: UIViewController ) { nativeAd?.handleClick(on: view) }
Objective-C
- (void)didRecordImpression { if (self.nativeAd) { [self.nativeAd recordImpression]; } } - (void)didRecordClickOnAssetWithName:(GADUnifiedNativeAssetIdentifier)assetName view:(UIView *)view viewController:(UIViewController *)viewController { if (self.nativeAd) { [self.nativeAd handleClickOnView:view]; } }
Vì lớp triển khai giao thức GADMediationNativeAd
sẽ tham chiếu đến đối tượng quảng cáo gốc của SDK mẫu, nên lớp đó có thể gọi phương thức thích hợp trên đối tượng đó để báo cáo một lượt nhấp hoặc lượt hiển thị. Xin lưu ý rằng phương thức didRecordClickOnAssetWithName:view:viewController:
sẽ nhận một thông số duy nhất: đối tượng View
tương ứng với thành phần quảng cáo gốc đã nhận được lượt nhấp đó.
Theo dõi lượt nhấp và lượt hiển thị bằng SDK đã dàn xếp
Một số SDK đã dàn xếp có thể muốn tự theo dõi lượt nhấp và lượt hiển thị. Trong trường hợp đó, bạn nên triển khai phương thức handlesUserClicks
và handlesUserImpressions
như hiển thị trong đoạn mã ở bên dưới. Bằng cách trả về YES
, bạn cho biết rằng sự kiện tuỳ chỉnh sẽ chịu trách nhiệm theo dõi các sự kiện này và sẽ thông báo cho SDK quảng cáo trên thiết bị di động của Google khi các sự kiện này xảy ra.
Những sự kiện tuỳ chỉnh ghi đè hoạt động theo dõi lượt nhấp và lượt hiển thị có thể sử dụng thông báo didRenderInView:
để truyền chế độ xem của quảng cáo gốc đến đối tượng quảng cáo gốc của SDK đã dàn xếp nhằm cho phép SDK đã dàn xếp thực hiện hoạt động theo dõi thực tế. SDK mẫu từ dự án mẫu sự kiện tuỳ chỉnh của chúng tôi (dự án chứa đoạn mã trong hướng dẫn này) không sử dụng phương pháp này, nhưng nếu có, mã sự kiện tuỳ chỉnh sẽ gọi phương thức setNativeAdView:view:
như minh hoạ trong đoạn mã dưới đây:
Swift
func handlesUserClicks() -> Bool { return true } func handlesUserImpressions() -> Bool { return true } func didRender( in view: UIView, clickableAssetViews: [GADNativeAssetIdentifier: UIView], nonclickableAssetViews: [GADNativeAssetIdentifier: UIView], viewController: UIViewController ) { // This method is called when the native ad view is rendered. Here you would pass the UIView // back to the mediated network's SDK. self.nativeAd?.setNativeAdView(view) }
Objective-C
- (BOOL)handlesUserClicks { return YES; } - (BOOL)handlesUserImpressions { return YES; } - (void)didRenderInView:(UIView *)view clickableAssetViews:(NSDictionary<GADNativeAssetIdentifier, UIView *> *) clickableAssetViews nonclickableAssetViews:(NSDictionary<GADNativeAssetIdentifier, UIView *> *) nonclickableAssetViews viewController:(UIViewController *)viewController { // This method is called when the native ad view is rendered. Here you would // pass the UIView back to the mediated network's SDK. Playing video using // SampleNativeAd's playVideo method [_nativeAd setNativeAdView:view]; }
Chuyển tiếp sự kiện dàn xếp đến SDK quảng cáo trên thiết bị di động của Google
Sau khi bạn gọi GADMediationNativeLoadCompletionHandler
bằng một quảng cáo đã tải, thì sau đó, bộ chuyển đổi có thể sử dụng đối tượng thực thể đại diện GADMediationNativeAdEventDelegate
được trả về để chuyển tiếp các sự kiện trình bày từ SDK của bên thứ ba vào SDK quảng cáo trên thiết bị di động của Google.
Điều quan trọng là sự kiện tuỳ chỉnh của bạn phải chuyển tiếp càng nhiều lệnh gọi lại này càng tốt để ứng dụng của bạn có thể nhận được các sự kiện tương đương này từ SDK quảng cáo trên thiết bị di động của Google. Dưới đây là ví dụ về cách sử dụng lệnh gọi lại:
Đến đây, bạn đã hoàn tất việc triển khai sự kiện tuỳ chỉnh cho quảng cáo gốc. Bạn có thể xem toàn bộ ví dụ trên GitHub.