تُسهِّل أدوات تطوير البرامج لإعلانات الوسائط التفاعلية عملية دمج إعلانات الوسائط المتعددة في مواقعك الإلكترونية وتطبيقاتك. يمكن لحِزم تطوير البرامج لإعلانات الوسائط التفاعلية طلب الإعلانات من أيّ خادم إعلانات متوافق مع نموذج عرض إعلانات الفيديو (VAST) وإدارة تشغيل الإعلانات في تطبيقاتك. باستخدام حِزم تطوير البرامج لإعلانات الوسائط التفاعلية من جهة العميل، يمكنك التحكّم في تشغيل فيديو المحتوى، بينما تتعامل حزمة تطوير البرامج مع تشغيل الإعلانات. يتم تشغيل الإعلانات في مشغّل فيديو منفصل موضوع أعلى مشغّل فيديو محتوى التطبيق.
يوضح هذا الدليل كيفية دمج حزمة IMA SDK في تطبيق مشغِّل فيديو بسيط. وإذا كنت ترغب في عرض نموذج عملية دمج مكتمل أو متابعته، يُرجى تنزيل BasicExample من GitHub.
نظرة عامة على IMA من جهة العميل
يتضمّن تنفيذ IMA من جهة العميل أربعة مكوّنات رئيسية لحزمة تطوير البرامج (SDK)، والتي يتم توضيحها في هذا الدليل:
IMAAdDisplayContainer
: عنصر حاوية يتم عرض الإعلانات فيه.IMAAdsLoader
: عنصر يطلب الإعلانات ويعالج الأحداث من الإعلانات ويطلب الردود. يجب إنشاء أداة تحميل إعلانات واحدة فقط في الوقت الحالي، والتي يمكن إعادة استخدامها طوال عمر التطبيق.IMAAdsRequest
: كائن يعرّف طلب الإعلانات. تحدِّد طلبات الإعلانات عنوان URL لعلامة إعلان نموذج عرض إعلانات الفيديو (VAST)، بالإضافة إلى مَعلمات إضافية، مثل سمات الإعلان.IMAAdsManager
: عنصر يحتوي على الاستجابة لطلب الإعلانات، ويتحكّم في تشغيل الإعلانات، ويستمع إلى أحداث الإعلانات التي تنشئها حزمة SDK
المتطلبات الأساسية
قبل البدء، يجب توفّر ما يلي:
- الإصدار 13 من Xcode أو إصدار أحدث
- CocoaPods (الخيار المفضّل) أو Swift Package Manager أو نسخة تم تنزيلها من حزمة تطوير البرامج لإعلانات الوسائط التفاعلية لنظام التشغيل tvOS
1. إنشاء مشروع Xcode جديد
في Xcode، أنشئ مشروعًا جديدًا لنظام التشغيل tvOS باستخدام Objective-C أو Swift. استخدِم BasicExample كاسم المشروع.
2. إضافة حزمة تطوير البرامج لإعلانات الوسائط التفاعلية إلى مشروع Xcode
تثبيت حزمة تطوير البرامج (SDK) باستخدام CocoaPods (الخيار المفضّل)
CocoaPods هو مدير تبعية لمشاريع Xcode وهو الطريقة التي يُنصح بها لتثبيت حزمة تطوير البرامج لإعلانات الوسائط التفاعلية. لمزيد من المعلومات حول تثبيت CocoaPods أو استخدامه، يُرجى الاطّلاع على مستندات CocoaPods. بعد تثبيت CocoaPods، اتّبِع التعليمات التالية لتثبيت حزمة تطوير البرامج لإعلانات الوسائط التفاعلية:
في الدليل نفسه الذي يتضمّن ملف BasicExample.xcodeproj، أنشِئ ملفًا نصيًا باسم Podfile وأضِف الإعدادات التالية:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '14' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.0' end
من الدليل الذي يحتوي على Podfile، شغِّل
pod install --repo-update
.تأكَّد من نجاح عملية التثبيت من خلال فتح ملف BasicExample.xcworkspace والتأكّد من أنّه يحتوي على مشروعَين: BasicExample وPods (التبعيات التي ثبَّتها CocoaPods).
تثبيت حزمة SDK باستخدام Swift Package Manager
تتوافق حزمة تطوير البرامج لإعلانات الوسائط التفاعلية مع Swift Package Manager اعتبارًا من الإصدار 4.8.2. اتبع الخطوات أدناه لاستيراد حزمة Swift.
في Xcode، ثبِّت حزمة Swift الخاصة بحزمة تطوير البرامج (SDK) لإعلانات الوسائط التفاعلية من خلال الانتقال إلى ملف > إضافة حِزم....
في رسالة المطالبة التي تظهر، ابحث عن مستودع IMA SDK Swift Package GitHub:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
اختر إصدار حزمة Swift لحزمة تطوير البرامج لإعلانات الوسائط التفاعلية الذي تريد استخدامه. بالنسبة إلى المشاريع الجديدة، ننصح باستخدام الإصدار الرئيسي التالي.
بعد الانتهاء، يحلّ Xcode تبعيات الحِزم ويصعدها في الخلفية. لمزيد من التفاصيل حول كيفية إضافة تبعيات الحزمة، يُرجى الاطّلاع على مقالة Apple.
تنزيل حزمة تطوير البرامج (SDK) وتثبيتها يدويًا
إذا لم تكن تريد استخدام CocoaPods، يمكنك تنزيل حزمة تطوير البرامج لإعلانات الوسائط التفاعلية وإضافتها يدويًا إلى مشروعك.
3- إنشاء مشغّل فيديو بسيط
أولاً، استخدِم مشغّل فيديو أساسيًا. في البداية، لا يستخدم هذا المشغّل حزمة تطوير البرامج لإعلانات الوسائط التفاعلية ولا يحتوي حتى الآن على أي طريقة لتشغيل التشغيل.
ViewController.m
Objective-C
#import "ViewController.h" #import <AVKit/AVKit.h> NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"; @interface ViewController () @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = UIColor.blackColor; [self setupContentPlayer]; } - (void)setupContentPlayer { // Create a content video player. NSURL *contentURL = [NSURL URLWithString:kContentURLString]; AVPlayer *player = [AVPlayer playerWithURL:contentURL]; self.contentPlayerViewController = [[AVPlayerViewController alloc] init]; self.contentPlayerViewController.player = player; self.contentPlayerViewController.view.frame = self.view.bounds; // Attach content video player to view hierarchy. [self showContentPlayer]; } // Add the content video player as a child view controller. - (void)showContentPlayer { [self addChildViewController:self.contentPlayerViewController]; self.contentPlayerViewController.view.frame = self.view.bounds; [self.view insertSubview:self.contentPlayerViewController.view atIndex:0]; [self.contentPlayerViewController didMoveToParentViewController:self]; } // Remove and detach the content video player. - (void)hideContentPlayer { // The whole controller needs to be detached so that it doesn't capture events from the remote. [self.contentPlayerViewController willMoveToParentViewController:nil]; [self.contentPlayerViewController.view removeFromSuperview]; [self.contentPlayerViewController removeFromParentViewController]; } @end
Swift
import AVFoundation import UIKit class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" var playerViewController: AVPlayerViewController! override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black; setUpContentPlayer() } func setUpContentPlayer() { // Load AVPlayer with path to your content. let contentURL! = URL(string: ViewController.ContentURLString) let player = AVPlayer(url: contentURL) playerViewController = AVPlayerViewController() playerViewController.player = player showContentPlayer() } func showContentPlayer() { self.addChild(playerViewController) playerViewController.view.frame = self.view.bounds self.view.insertSubview(playerViewController.view, at: 0) playerViewController.didMove(toParent:self) } func hideContentPlayer() { // The whole controller needs to be detached so that it doesn't capture events from the remote. playerViewController.willMove(toParent:nil) playerViewController.view.removeFromSuperview() playerViewController.removeFromParent() } }
4. استيراد حزمة تطوير البرامج لإعلانات الوسائط التفاعلية
بعد ذلك، أضِف إطار عمل IMA باستخدام عبارة استيراد أسفل عمليات الواردة الحالية.
ViewController.m
Objective-C
#import "ViewController.h" #import <AVKit/AVKit.h> #import <GoogleInteractiveMediaAds/GoogleInteractiveMediaAds.h> NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4";
Swift
import AVFoundation import GoogleInteractiveMediaAds import UIKit class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"
5- تنفيذ أداة تتبُّع رأس تشغيل المحتوى وميزة "مراقبة نهاية البث"
لتشغيل الإعلانات أثناء التشغيل، يجب أن تتتبّع حزمة تطوير البرامج لإعلانات الوسائط التفاعلية الموضع الحالي
لمحتوى الفيديو. لإجراء ذلك، أنشئ فئة تنفِّذ
IMAContentPlayhead
. إذا كنت تستخدم AVPlayer
، كما هو موضّح في هذا المثال، ستوفّر حزمة تطوير البرامج (SDK) الفئة IMAAVPlayerContentPlayhead
التي تنفّذ ذلك نيابةً عنك.
إذا لم تكن تستخدم AVPlayer
، عليك تنفيذ IMAContentPlayhead
على
صف من إنشاءك.
عليك أيضًا إبلاغ حزمة SDK عند انتهاء تشغيل المحتوى حتى تتمكّن من
عرض الإعلانات ما بعد التشغيل. ويتم ذلك من خلال طلب الرقم contentComplete
على IMAAdsLoader
، باستخدام AVPlayerItemDidPlayToEndTimeNotification
.
ViewController.m
Objective-C
... @interface ViewController () @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end ... - (void)setupContentPlayer { // Create a content video player. NSURL *contentURL = [NSURL URLWithString:kContentURLString]; AVPlayer *player = [AVPlayer playerWithURL:contentURL]; self.contentPlayerViewController = [[AVPlayerViewController alloc] init]; self.contentPlayerViewController.player = player; self.contentPlayerViewController.view.frame = self.view.bounds; self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayerViewController.player]; // Track end of content. AVPlayerItem *contentPlayerItem = self.contentPlayerViewController.player.currentItem; [NSNotificationCenter.defaultCenter addObserver:self selector:@selector(contentDidFinishPlaying:) name:AVPlayerItemDidPlayToEndTimeNotification object:contentPlayerItem]; // Attach content video player to view hierarchy. [self showContentPlayer]; } ... - (void)contentDidFinishPlaying:(NSNotification *)notification {} - (void)dealloc { [NSNotificationCenter.defaultCenter removeObserver:self]; } @end
Swift
... class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! deinit { NotificationCenter.default.removeObserver(self) } ... func setUpContentPlayer() { // Load AVPlayer with path to your content. let contentURL! = URL(string: ViewController.ContentURLString) let player = AVPlayer(url: contentURL) playerViewController = AVPlayerViewController() playerViewController.player = player // Set up your content playhead and contentComplete callback. contentPlayhead = IMAAVPlayerContentPlayhead(avPlayer: player) NotificationCenter.default.addObserver( self, selector: #selector(ViewController.contentDidFinishPlaying(_:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem); showContentPlayer() } ... @objc func contentDidFinishPlaying(_ notification: Notification) { adsLoader.contentComplete() } }
6- إعداد أداة تحميل الإعلانات وتقديم طلب إعلانات
لطلب مجموعة من الإعلانات، عليك إنشاء مثيل IMAAdsLoader
.
يمكن استخدام أداة التحميل هذه لمعالجة عناصر IMAAdsRequest
المرتبطة بعنوان URL لعلامة إعلان
محدّد.
من أفضل الممارسات الاحتفاظ بمثيل واحد فقط من IMAAdsLoader
طوال
دورة حياة تطبيقك. لتقديم طلبات إعلانات إضافية، أنشئ عنصر
IMAAdsRequest
جديدًا، ولكن أعِد استخدام IMAAdsLoader
نفسه. لمزيد من المعلومات، اطّلِع على الأسئلة الشائعة عن حزمة تطوير البرامج لإعلانات الوسائط التفاعلية.
ViewController.m
Objective-C
... NSString *const kContentURLString = @"https://storage.googleapis.com/interactive-media-ads/media/stock.mp4"; NSString *const kAdTagURLString = @"https://pubads.g.doubleclick.net/gampad/ads?" @"iu=/21775744923/external/vmap_ad_samples&sz=640x480&" @"cust_params=sample_ar%3Dpremidpostlongpod&" @"ciu_szs=300x250&gdfp_req=1&ad_rule=1&output=vmap&unviewed_position_start=1&" @"env=vp&impl=s&cmsid=496&vid=short_onecue&correlator="; @interface ViewController () @property(nonatomic) IMAAdsLoader *adsLoader; @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = UIColor.blackColor; [self setupContentPlayer]; [self setupAdsLoader]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self requestAds]; } - (void)setupAdsLoader { self.adsLoader = [[IMAAdsLoader alloc] init]; } - (void)requestAds { // Pass the main view as the container for ad display. IMAAdDisplayContainer *adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view]; IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString adDisplayContainer:adDisplayContainer contentPlayhead:self.contentPlayhead userContext:nil]; [self.adsLoader requestAdsWithRequest:request]; } ... - (void)contentDidFinishPlaying:(NSNotification *)notification { // Notify the SDK that the postrolls should be played. [self.adsLoader contentComplete]; } ... @end
Swift
... class ViewController: UIViewController { static let ContentURLString = "https://storage.googleapis.com/interactive-media-ads/media/stock.mp4" static let AdTagURLString = "https://pubads.g.doubleclick.net/gampad/ads?iu=/21775744923/external/single_ad_samples&sz=640x480&cust_params=sample_ct%3Dlinear&ciu_szs=300x250%2C728x90&gdfp_req=1&output=vast&unviewed_position_start=1&env=vp&impl=s&correlator=" var adsLoader: IMAAdsLoader! var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! ... override func viewDidLoad() { super.viewDidLoad() self.view.backgroundColor = UIColor.black; setUpContentPlayer() setUpAdsLoader() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated); requestAds() } ... func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) } func requestAds() { // Create ad display container for ad rendering. let adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view) // Create an ad request with your ad tag, display container, and optional user context. let request = IMAAdsRequest( adTagUrl: ViewController.AdTagURLString, adDisplayContainer: adDisplayContainer, contentPlayhead: contentPlayhead, userContext: nil) adsLoader.requestAds(with: request) } @objc func contentDidFinishPlaying(_ notification: Notification) { adsLoader.contentComplete() } }
7- إعداد مفوّض لتحميل الإعلانات
عند حدوث حدث تحميل ناجح، يُطلِق IMAAdsLoader
طريقة adsLoadedWithData
للمفوّض المحدّد له، مع تمريرها مثيلًا من IMAAdsManager
. يمكنك
بعد ذلك بدء أداة إدارة الإعلانات التي تحمّل الإعلانات الفردية كما هو محدّد
بواسطة الاستجابة لعنوان URL لعلامة الإعلان.
بالإضافة إلى ذلك، احرص على معالجة أي أخطاء قد تحدث أثناء عملية التحميل. إذا لم يتم تحميل الإعلانات، تأكّد من أن تشغيل الوسائط مستمر بدون إعلانات حتى لا يتداخل مع تجربة المستخدم.
ViewController.m
Objective-C
... @interface ViewController () <IMAAdsLoaderDelegate> @property(nonatomic) IMAAdsLoader *adsLoader; @property(nonatomic) IMAAdsManager *adsManager; @property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead; @property(nonatomic) AVPlayerViewController *contentPlayerViewController; @end @implementation ViewController ... - (void)setupAdsLoader { self.adsLoader = [[IMAAdsLoader alloc] init]; self.adsLoader.delegate = self; } ... #pragma mark - IMAAdsLoaderDelegate - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Initialize and listen to the ads manager loaded for this request. self.adsManager = adsLoadedData.adsManager; [self.adsManager initializeWithAdsRenderingSettings:nil]; } - (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData { // Fall back to playing content. NSLog(@"Error loading ads: %@", adErrorData.adError.message); [self.contentPlayerViewController.player play]; } @end
Swift
... class ViewController: UIViewController, IMAAdsLoaderDelegate { ... var adsLoader: IMAAdsLoader! var adsManager: IMAAdsManager! var contentPlayhead: IMAAVPlayerContentPlayhead? var playerViewController: AVPlayerViewController! ... func setUpAdsLoader() { adsLoader = IMAAdsLoader(settings: nil) adsLoader.delegate = self } ... // MARK: - IMAAdsLoaderDelegate func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) { adsManager = adsLoadedData.adsManager adsManager.initialize(with: nil) } func adsLoader(_ loader: IMAAdsLoader!, failedWith adErrorData: IMAAdLoadingErrorData!) { print("Error loading ads: " + adErrorData.adError.message) showContentPlayer() playerViewController.player?.play() } }
8. إعداد مفوّض في "مدير إعلانات Google"
أخيرًا، لإدارة الأحداث وتغييرات الحالة، يحتاج مدير الإعلانات إلى مفوَّض له. وتتوفر في IMAAdManagerDelegate
طرق للتعامل مع أحداث الإعلانات وأخطائها،
بالإضافة إلى طرق لبدء تشغيل محتوى الفيديو وإيقافه مؤقتًا.
جارٍ بدء التشغيل
هناك العديد من الأحداث التي يمكن استخدام الطريقة didReceiveAdEvent
للتعامل معها،
ولكن في هذا المثال الأساسي، ما عليك سوى الانتظار إلى أن يحدث الحدث LOADED
لإعلام مدير الإعلانات ببدء تشغيل المحتوى والإعلانات.
ViewController.m
Objective-C
@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate> ... - (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData { // Initialize and listen to the ads manager loaded for this request. self.adsManager = adsLoadedData.adsManager; self.adsManager.delegate = self; [self.adsManager initializeWithAdsRenderingSettings:nil]; } ... #pragma mark - IMAAdsManagerDelegate - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event { // Play each ad once it has loaded. if (event.type == kIMAAdEvent_LOADED) { [adsManager start]; } } ...
Swift
... class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate { ... func adsLoader(_ loader: IMAAdsLoader!, adsLoadedWith adsLoadedData: IMAAdsLoadedData!) { // Grab the instance of the IMAAdsManager and set yourself as the delegate. adsManager = adsLoadedData.adsManager adsManager.delegate = self adsManager.initialize(with: nil) } ... // MARK: - IMAAdsManagerDelegate func adsManager(_ adsManager: IMAAdsManager!, didReceive event: IMAAdEvent!) { // Play each ad once it has been loaded if event.type == IMAAdEventType.LOADED { adsManager.start() } } ...
معالجة الأخطاء
أضِف أيضًا معالِجًا لأخطاء الإعلانات. إذا حدث خطأ، كما هو الحال في الخطوة السابقة، فاستأنف تشغيل المحتوى.
ViewController.m
Objective-C
... - (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error { // Fall back to playing content. NSLog(@"AdsManager error: %@", error.message); [self showContentPlayer]; [self.contentPlayerViewController.player play]; } @end
Swift
... func adsManager(_ adsManager: IMAAdsManager!, didReceive error: IMAAdError!) { // Fall back to playing content print("AdsManager error: " + error.message) showContentPlayer() playerViewController.player?.play() }
بدء أحداث التشغيل والإيقاف المؤقت
تُستخدَم الطريقتان المفوَّضتان الأخيرتان اللتان عليك تنفيذهما لبدء أحداث التشغيل والتوقف مؤقتًا في محتوى الفيديو الأساسي، وذلك عندما تطلب ذلك أداة تطوير البرامج لإعلانات الوسائط التفاعلية. يؤدي تفعيل ميزة الإيقاف المؤقت والتشغيل عند الطلب إلى منع المستخدم من تفويت أجزاء من محتوى الفيديو عند عرض الإعلانات.
ViewController.m
Objective-C
... - (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager { // Pause the content for the SDK to play ads. [self.contentPlayerViewController.player pause]; [self hideContentPlayer]; } - (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager { // Resume the content since the SDK is done playing ads (at least for now). [self showContentPlayer]; [self.contentPlayerViewController.player play]; } @end
Swift
... func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager!) { // Pause the content for the SDK to play ads. playerViewController.player?.pause() hideContentPlayer() } func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager!) { // Resume the content since the SDK is done playing ads (at least for now). showContentPlayer() playerViewController.player?.play() } }
هذا كل شيء! أنت الآن تطلب الإعلانات وتعرضها باستخدام حزمة تطوير البرامج لإعلانات الوسائط التفاعلية. لمزيد من المعلومات عن ميزات حزمة تطوير البرامج (SDK) الإضافية، يمكنك الاطّلاع على الأدلّة الأخرى أو النماذج على GitHub.
الخطوات التالية
لتحقيق أقصى قدر من الأرباح من الإعلانات على منصة tvOS، عليك طلب إذن "شفافية التطبيقات وتتبُّعها" لاستخدام معرّف IDFA.