ערכות IMA SDK מאפשרות לשלב בקלות מודעות מולטימדיה באתרים ובאפליקציות. IMA SDKs יכולים לשלוח בקשות למודעות מכל שרת מודעות שתואם ל-VAST ולנהל את ההפעלה של המודעות באפליקציות. עם IMA SDK בצד הלקוח, אתם שומרים על שליטה בהפעלת תוכן הווידאו, בזמן שה-SDK מטפל בהפעלת המודעה. המודעות מוצגות בנגן וידאו נפרד שממוקם מעל נגן הווידאו של התוכן באפליקציה.
במדריך הזה מוסבר איך לשלב את IMA SDK באפליקציה של נגן וידאו. כדי לראות דוגמה לשילוב מלא או לפעול לפי ההוראות, אפשר להוריד את BasicExample מ-GitHub.
סקירה כללית על IMA בצד הלקוח
הטמעה של IMA בצד הלקוח כוללת ארבעה רכיבי SDK עיקריים, שמוסברים במדריך הזה:
-
IMAAdDisplayContainer: אובייקט מאגר שמציין איפה IMA מעבד רכיבי ממשק משתמש של מודעות ומודד את הניראות, כולל Active View ו-Open Measurement. -
IMAAdsLoader: אובייקט שמבקש מודעות ומטפל באירועים מתגובות לבקשות מודעות. צריך ליצור רק מופע אחד של ads loader, שאפשר להשתמש בו שוב לאורך חיי האפליקציה. -
IMAAdsRequest: אובייקט שמגדיר בקשה להצגת מודעות. בבקשות להצגת מודעות מצוינת כתובת ה-URL של תג המודעה בפורמט VAST, וגם פרמטרים נוספים, כמו מידות המודעה. -
IMAAdsManager: אובייקט שמכיל את התגובה לבקשת המודעות, שולט בהפעלת המודעות ומאזין לאירועי מודעות שמופעלים על ידי ה-SDK.
דרישות מוקדמות
לפני שמתחילים, צריך:
- Xcode 13 ואילך
- Swift Package Manager, CocoaPods או עותק להורדה של IMA SDK ל-tvOS
1. יצירת פרויקט חדש ב-Xcode
ב-Xcode, יוצרים פרויקט tvOS חדש באמצעות Objective-C או Swift. משתמשים ב-BasicExample כשם הפרויקט.
2. הוספת IMA SDK לפרויקט Xcode
התקנה של IMA SDK באמצעות Swift Package Manager
החל מגרסה 4.8.2, Interactive Media Ads SDK תומך ב-Swift Package Manager. כדי לייבא את חבילת Swift, פועלים לפי השלבים הבאים.
ב-Xcode, מתקינים את IMA SDK Swift Package (חבילת IMA SDK Swift) על ידי מעבר אל File > Add Packages... (קובץ > הוספת חבילות...).
בהנחיה שמופיעה, מחפשים את מאגר IMA SDK Swift Package GitHub:
https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvosבוחרים את הגרסה של IMA SDK Swift Package שרוצים להשתמש בה. לפרויקטים חדשים, מומלץ להשתמש באפשרות עד הגרסה הראשית הבאה.
אחרי שתסיימו, פלטפורמת Xcode תטפל ביחסי התלות שבחבילה ותוריד אותם ברקע. לפרטים נוספים על הוספת תלות בחבילה, אפשר לעיין במאמר של Apple.
התקנה של IMA SDK באמצעות CocoaPods
כדי להתקין את IMA SDK, משתמשים ב-CocoaPods. מידע נוסף על התקנה או שימוש ב-CocoaPods זמין במסמכי העזרה של CocoaPods. אחרי שמתקינים את CocoaPods, מבצעים את הפעולות הבאות:
באותה תיקייה שבה נמצא הקובץ BasicExample.xcodeproj, יוצרים קובץ טקסט בשם Podfile ומוסיפים את ההגדרות הבאות:
source 'https://github.com/CocoaPods/Specs.git' platform :tvos, '15' target "BasicExample" do pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.16.0' endמהספרייה שמכילה את Podfile, מריצים את הפקודה
pod install --repo-updateכדי לוודא שההתקנה בוצעה בהצלחה, פותחים את הקובץ BasicExample.xcworkspace ומוודאים שהוא מכיל שני פרויקטים: BasicExample ו-Pods (התלויות שהותקנו על ידי CocoaPods).
הורדה והתקנה ידניות של IMA SDK
אם אתם לא רוצים להשתמש ב-CocoaPods, אתם יכולים להוריד את IMA SDK ולהוסיף אותו לפרויקט באופן ידני.
3. ייבוא של IMA SDK
מוסיפים את מסגרת IMA באמצעות הצהרת ייבוא.
Objective-C
#import "ViewController.h"
#import <AVKit/AVKit.h>
@import GoogleInteractiveMediaAds;
Swift
import AVFoundation
import GoogleInteractiveMediaAds
import UIKit
4. יצירת נגן וידאו ושילוב של IMA SDK
בדוגמה הבאה מופעל IMA SDK:
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&cmsid=496&vid=short_onecue&correlator=";
@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
@property(nonatomic) IMAAdsLoader *adsLoader;
@property(nonatomic) IMAAdDisplayContainer *adDisplayContainer;
@property(nonatomic) IMAAdsManager *adsManager;
@property(nonatomic) IMAAVPlayerContentPlayhead *contentPlayhead;
@property(nonatomic) AVPlayerViewController *contentPlayerViewController;
@property(nonatomic, getter=isAdBreakActive) BOOL adBreakActive;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor blackColor];
[self setupAdsLoader];
[self setupContentPlayer];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self requestAds];
}
// 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 resume events from the
// remote and play content underneath the ad.
[self.contentPlayerViewController willMoveToParentViewController:nil];
[self.contentPlayerViewController.view removeFromSuperview];
[self.contentPlayerViewController removeFromParentViewController];
}
Swift
class ViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
static let contentURLString =
"https://devstreaming-cdn.apple.com/videos/streaming/examples/"
+ "img_bipbop_adv_example_fmp4/master.m3u8"
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&correlator="
var adsLoader: IMAAdsLoader!
var adDisplayContainer: IMAAdDisplayContainer!
var adsManager: IMAAdsManager!
var contentPlayhead: IMAAVPlayerContentPlayhead?
var playerViewController: AVPlayerViewController!
var adBreakActive = false
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.black
setUpContentPlayer()
setUpAdsLoader()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
requestAds()
}
בדוגמה הזו, הפונקציה viewDidLoad() מאתחלת את IMAAdsLoader, והפונקציה viewDidAppear() שולחת בקשות להצגת מודעות ברגע שהתצוגה גלויה. שיטות עזר
showContentPlayer() ו-hideContentPlayer() מחליפות את מצב החשיפה של התוכן במהלך
הפעלת מודעות.
בדוגמה הזו נעשה שימוש במשתנה הקבוע adTagURLString כדי להגדיר את תג המודעה של VAST לבקשה להצגת מודעה, וברכיבים הבאים כדי לנהל את IMA SDK:
-
adsLoader: מטפל בבקשות למודעות ובתגובות. מומלץ להשתמש במופע יחיד למחזור החיים של האפליקציה. -
adDisplayContainer: מציין את התצוגה לעיבוד מודעות. -
adsManager: מנהל את הפעלת המודעות ומאזין לאירועים שקשורים למודעות. -
contentPlayhead: עוקב אחרי התקדמות התוכן כדי להפעיל הפסקות למודעות באמצע הסרטון. -
adBreakActive: מציין אם מוצגת הפסקה מסחרית כדי למנוע דילוג על מודעות.
5. הטמעה של מעקב אחר מיקום ההפעלה של התוכן ושל צופה בסיום הסטרימינג
כדי להציג מודעות באמצע הסרטון (mid-roll), IMA SDK צריך לעקוב אחרי המיקום הנוכחי של תוכן הווידאו. כדי לעשות זאת, יוצרים מחלקה שמטמיעה את
IMAContentPlayhead. אם אתם משתמשים ב-AVPlayer, כמו בדוגמה הזו, ה-SDK מספק את המחלקה IMAAVPlayerContentPlayhead שמבצעת את הפעולה הזו בשבילכם.
אם אתם לא משתמשים ב-AVPlayer, אתם צריכים להטמיע את IMAContentPlayhead בכיתה משלכם.
Objective-C
- (void)setupContentPlayer {
// Create a content video player. Create a playhead to track content progress so the SDK knows
// when to play ads in a VMAP playlist.
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];
}
Swift
func setUpContentPlayer() {
// Load AVPlayer with path to our content.
let contentURL = URL(string: ViewController.contentURLString)!
let player = AVPlayer(url: contentURL)
playerViewController = AVPlayerViewController()
playerViewController.player = player
// Set up our 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()
}
צריך גם להודיע ל-SDK מתי התוכן סיים את ההפעלה כדי שיוכל להציג מודעות אחרי הפעלת התוכן. כדי לעשות את זה, קוראים ל-contentComplete ב-IMAAdsLoader באמצעות AVPlayerItemDidPlayToEndTimeNotification.
Objective-C
- (void)contentDidFinishPlaying:(NSNotification *)notification {
// Notify the SDK that the postrolls should be played.
[self.adsLoader contentComplete];
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
Swift
@objc func contentDidFinishPlaying(_ notification: Notification) {
adsLoader.contentComplete()
}
6. מאתחלים את הכלי לטעינת מודעות ושולחים בקשה להצגת מודעות
כדי לבקש קבוצה של מודעות, צריך ליצור מופע של IMAAdsLoader.
אפשר להשתמש בטוען הזה כדי לעבד אובייקטים של IMAAdsRequest שמשויכים לכתובת URL ספציפית של תג פרסום.
מומלץ לשמור רק מופע אחד של IMAAdsLoader לאורך כל מחזור החיים של האפליקציה. כדי לשלוח בקשות נוספות להצגת מודעות, צריך ליצור אובייקט IMAAdsRequest חדש, אבל להשתמש מחדש באותו IMAAdsLoader. מידע נוסף זמין בשאלות הנפוצות בנושא IMA SDK.
Objective-C
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] init];
self.adsLoader.delegate = self;
}
- (void)requestAds {
// Pass the main view as the container for ad display.
self.adDisplayContainer = [[IMAAdDisplayContainer alloc] initWithAdContainer:self.view
viewController:self];
IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kAdTagURLString
adDisplayContainer:self.adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoader requestAdsWithRequest:request];
}
Swift
func setUpAdsLoader() {
adsLoader = IMAAdsLoader(settings: nil)
adsLoader.delegate = self
}
func requestAds() {
// Create ad display container for ad rendering.
adDisplayContainer = IMAAdDisplayContainer(adContainer: self.view, viewController: self)
// Create an ad request with our ad tag, display container, and optional user context.
let request = IMAAdsRequest(
adTagUrl: ViewController.adTagURLString,
adDisplayContainer: adDisplayContainer,
contentPlayhead: contentPlayhead,
userContext: nil)
adsLoader.requestAds(with: request)
}
7. הגדרת נציג לטעינת מודעות
באירוע טעינה מוצלח, IMAAdsLoader מפעיל את השיטה adsLoadedWithData של הנציג שהוקצה לו, ומעביר לו מופע של IMAAdsManager. לאחר מכן תוכלו להפעיל את כלי ניהול המודעות, שיטען את המודעות הבודדות, כפי שהוגדר בתגובה לכתובת ה-URL של תג המודעה.
בנוסף, חשוב לטפל בכל השגיאות שעלולות להתרחש במהלך תהליך הטעינה. אם המודעות לא נטענות, חשוב לוודא שהפעלת המדיה נמשכת בלי מודעות, כדי לא לפגוע בחוויית המשתמש.
Objective-C
#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.delegate = self;
[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];
}
Swift
func adsLoader(_ loader: IMAAdsLoader, adsLoadedWith adsLoadedData: IMAAdsLoadedData) {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate.
adsManager = adsLoadedData.adsManager
adsManager.delegate = self
adsManager.initialize(with: nil)
}
func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
print("Error loading ads: \(adErrorData.adError.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
8. הגדרת הרשאת גישה לחשבון ניהול המודעות
לבסוף, כדי לנהל אירועים ושינויים במצב, למנהל המודעות צריך להיות נציג משלו. ל-IMAAdManagerDelegate יש שיטות לטיפול באירועים ובשגיאות שקשורות למודעות, וגם שיטות להפעלה ולהשהיה של תוכן הווידאו.
התחלת ההפעלה
יש הרבה אירועים שאפשר להשתמש בשיטה didReceiveAdEvent כדי לטפל בהם.
בדוגמה הבסיסית הזו, המערכת מאזינה לאירוע LOADED כדי להורות למנהל המודעות להתחיל בהפעלה של תוכן ומודעות. ה-IMA SDK מפעיל את האירוע ICON_FALLBACK_IMAGE_CLOSED כשמשתמש סוגר תיבת דו-שיח של חלופה לסמל אחרי שהוא מקיש על סמל. אחרי הפעולה הזו, הפעלת המודעה תמשיך.
Objective-C
#pragma mark - IMAAdsManagerDelegate
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
switch (event.type) {
case kIMAAdEvent_LOADED: {
// Play each ad once it has loaded.
[adsManager start];
break;
}
case kIMAAdEvent_ICON_FALLBACK_IMAGE_CLOSED: {
// Resume ad after user has closed dialog.
[adsManager resume];
break;
}
default:
break;
}
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
switch event.type {
case IMAAdEventType.LOADED:
// Play each ad once it has been loaded.
adsManager.start()
case IMAAdEventType.ICON_FALLBACK_IMAGE_CLOSED:
// Resume playback after the user has closed the dialog.
adsManager.resume()
default:
break
}
}
טיפול בשגיאות
כדאי להוסיף גם handler לשגיאות שקשורות למודעות. אם מתרחשת שגיאה, כמו בשלב הקודם, ממשיכים בהפעלת התוכן.
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];
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
// Fall back to playing content
print("AdsManager error: \(error.message ?? "No error message available.")")
showContentPlayer()
playerViewController.player?.play()
}
הפעלת אירועי הפעלה והשהיה
שתי שיטות הנציג האחרונות שצריך להטמיע משמשות להפעלת אירועי הפעלה והשהיה בתוכן הווידאו הבסיסי, כשמתקבלת בקשה מ-IMA SDK. הפעלת ההשהיה וההפעלה כשמתקבלת בקשה לכך מונעת מצב שבו המשתמש מפספס חלקים מתוכן הווידאו כשהמודעות מוצגות.
Objective-C
- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
// Pause the content for the SDK to play ads.
[self.contentPlayerViewController.player pause];
[self hideContentPlayer];
// Trigger an update to send focus to the ad display container.
self.adBreakActive = YES;
[self setNeedsFocusUpdate];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
// Resume the content since the SDK is done playing ads (at least for now).
[self showContentPlayer];
[self.contentPlayerViewController.player play];
// Trigger an update to send focus to the content player.
self.adBreakActive = NO;
[self setNeedsFocusUpdate];
}
Swift
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
// Pause the content for the SDK to play ads.
playerViewController.player?.pause()
hideContentPlayer()
// Trigger an update to send focus to the ad display container.
adBreakActive = true
setNeedsFocusUpdate()
}
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
// Resume the content since the SDK is done playing ads (at least for now).
showContentPlayer()
playerViewController.player?.play()
// Trigger an update to send focus to the content player.
adBreakActive = false
setNeedsFocusUpdate()
}
זהו! מעכשיו אתם שולחים בקשות למודעות ומציגים אותן באמצעות IMA SDK. כדי לקבל מידע על תכונות נוספות של ה-SDK, אפשר לעיין במדריכים האחרים או בדוגמאות ב-GitHub.
השלבים הבאים
כדי להגדיל את ההכנסות מפרסום בפלטפורמת tvOS, צריך לבקש הרשאה לשקיפות בנושא מעקב באפליקציות כדי להשתמש ב-IDFA.