ערכות IMA SDK מאפשרות לכם לשלב בקלות מודעות מולטימדיה באתרים ובאפליקציות שלכם. ערכות IMA SDK יכולות לבקש מודעות מכל שרת מודעות שתואם ל-VAST ולנהל את הפעלת המודעות באפליקציות שלכם. בעזרת ערכות SDK בצד הלקוח של IMA, יש לך שליטה על הפעלת סרטונים בתוכן, בזמן שה-SDK מטפל בהפעלת המודעות. המודעות מופעלות נגן וידאו נפרד שממוקם מעל נגן הווידאו של התוכן של האפליקציה.
המדריך הזה מדגים איך לשלב את IMA SDK בנגן וידאו פשוט אפליקציה. אם אתם רוצים להציג טעימה מלאה או לעקוב אחריו של השילוב, מורידים את BasicExample מ- GitHub.
סקירה כללית בצד הלקוח של IMA
ההטמעה של IMA בצד הלקוח כוללת ארבעה רכיבי SDK עיקריים, שמודגמת במדריך זה:
IMAAdDisplayContainer
: אובייקט מאגר תגים שבו מתבצעות מודעות.IMAAdsLoader
: אובייקט ששולח מודעות ומטפל באירועים מתגובות לבקשות להצגת מודעות. צריך רק ליצור טוען מודעות אחד, שניתן להשתמש בו שוב במהלך חיי האפליקציה.IMAAdsRequest
: אובייקט שמגדיר בקשה להצגת מודעות. בקשות להצגת מודעות מציינות את כתובת ה-URL של תג המודעה מסוג VAST, וגם פרמטרים נוספים, כמו מאפייני מודעה.IMAAdsManager
: אובייקט שמכיל את התגובה לבקשה להצגת מודעה, שולט בהפעלת המודעה ומאזינים למודעה אירועים שהופעלו על ידי ה-SDK.
דרישות מוקדמות
לפני שמתחילים, צריך:
- Xcode 13 ואילך
- CocoaPods (מועדף), Swift Package Manager, או עותק של ההורדה IMA SDK ל-tvOS
1. יצירת פרויקט Xcode חדש
ב-Xcode, יוצרים פרויקט tvOS חדש באמצעות Objective-C או Swift. כדאי להשתמש BasicExample הוא שם הפרויקט.
2. הוספת IMA SDK לפרויקט Xcode
התקנת ה-SDK באמצעות CocoaPods (מועדף)
CocoaPods הוא מנהל יחסי תלות לפרויקטים של Xcode, ומומלץ להשתמש בו להתקנת ה-IMA SDK. מידע נוסף על התקנה או שימוש CocoaPods, אפשר לעיין במסמכי התיעוד של CocoaPods. אחרי ש אם התקנת את CocoaPods, יש לפעול לפי ההוראות הבאות כדי להתקין את IMA SDK:
באותה ספרייה כמו הקובץ 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
ב-Interactive Media Ads SDK יש תמיכה ב-Swift Package חשבון ניהול החל מגרסה 4.8.2. פועלים לפי השלבים הבאים כדי לייבא את חבילת Swift.
ב-Xcode, כדי להתקין את חבילת Swift של IMA SDK, עוברים אל קובץ > Add Packs... (הוספת חבילות).
בהנחיה שמופיעה, מחפשים את IMA SDK SWIFT Package GitHub מאגר:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
בוחרים את הגרסה של IMA SDK SWIFT Package שבה רוצים להשתמש. לפרויקטים חדשים, מומלץ להשתמש ב-Up to Next Major Version.
בסיום, Xcode פותר את יחסי התלות של החבילות מוריד אותן ברקע. לפרטים נוספים על הוספת חבילה של יחסי התלות, המאמר של Apple.
הורדה והתקנה ידנית של ה-SDK
אם אינך רוצה להשתמש ב-CocoaPods, אפשר להוריד את IMA SDK באופן ידני ומוסיפים אותו לפרויקט.
3. יצירת נגן וידאו פשוט
ראשית, מטמיעים נגן וידאו בסיסי. בהתחלה, הנגן הזה לא משתמש IMA SDK ועדיין לא כולל שיטה להפעלת הפעלה.
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 SDK
לאחר מכן, הוסיפו את מסגרת ה-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. הטמעת מעקב אחר המיקום הנוכחי של התוכן וצפייה בסוף השידור
כדי להפעיל מודעות באמצע סרטון, IMA SDK צריך לעקוב אחר המיקום הנוכחי
של תוכן הווידאו שלכם. כדי לעשות זאת, צריך ליצור מחלקה שמממשת
IMAContentPlayhead
אם אתם משתמשים ב-AVPlayer
, כמו בדוגמה הזו,
ה-SDK מספק את המחלקה IMAAVPlayerContentPlayhead
שמבצעת את הפעולה הזו בשבילכם.
אם לא משתמשים ב-AVPlayer
, צריך להטמיע את IMAContentPlayhead
ב
כיתה משלכם.
אתם גם צריכים להודיע ל-SDK כשהתוכן שלכם מסתיים, כדי שהוא יוכל
להציג מודעות בסוף הסרטון (post-roll). כדי לעשות זאת, צריך להתקשר אל 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
אובייקטים שמשויכים אל
כתובת האתר של תג המודעה שצוין.
מומלץ לתחזק רק מופע אחד של IMAAdsLoader
בכל רחבי
במחזור החיים של האפליקציה. כדי לשלוח בקשות נוספות להצגת מודעות, צריך ליצור
אובייקט IMAAdsRequest
, אבל יש להשתמש שוב באותו IMAAdsLoader
. לקבלת מידע נוסף
מידע נוסף זמין במאמר שאלות נפוצות בנושא IMA SDK.
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
. שלך
יכול לאתחל את מנהל המודעות, שטוען כל מודעה בנפרד, כפי שמוגדר
התגובה לכתובת האתר של תג המודעה.
בנוסף, חשוב לטפל בשגיאות שעלולות להתרחש במהלך הטעינה תהליך האימות. אם מודעות לא נטענות, צריך לוודא שהפעלת המדיה נמשכת, מבלי כדי לא להפריע לחוויית המשתמש.
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. איך נותנים הרשאה לניהול מודעות
לבסוף, כדי לנהל אירועים ושינויים במצב (State), מנהל המודעות צריך לתת למישהו אחר גישה
משלו. ב-IMAAdManagerDelegate
יש שיטות לטיפול בשגיאות ובאירועים של מודעות,
וגם שיטות להפעלה והשהיה בתוכן הווידאו.
ההפעלה מתחילה
יש אירועים רבים שאפשר להשתמש בהם ב-method 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() } } ...
טיפול בשגיאות
להוסיף גם handler לשגיאות במודעות. אם תתרחש שגיאה, כמו בדוגמה הקודמת כדי להמשיך את הפעלת התוכן.
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() }
הפעלת אירועי הפעלה והשהיה
שתי השיטות האחרונות להענקת גישה שצריך להטמיע משמשות להפעלת הפעלה להשהות אירועים בתוכן הווידאו המקורי, כאשר הדבר נדרש על ידי ה-IMA SDK. הפעלת השהיה והפעלה כשנשלחת בקשה מונעת מהמשתמש לפספס חלקים של תוכן הווידאו כשמוצגות מודעות.
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() } }
זהו! זו בקשה להצגת מודעות באמצעות ה-IMA SDK. למידה על תכונות SDK נוספות, אפשר לקרוא מדריכים אחרים או דוגמאות ב-GitHub.
השלבים הבאים
כדי להגדיל את ההכנסות מפרסום בפלטפורמת tvOS, צריך לבקש הרשאה לשקיפות ולמעקב באפליקציה לשימוש ב-IDFA.