IMA SDK ช่วยให้การผสานรวมโฆษณามัลติมีเดียลงในเว็บไซต์และแอปเป็นเรื่องง่าย IMA SDK สามารถขอโฆษณาจากเซิร์ฟเวอร์โฆษณาที่ สอดคล้องกับ VAST และจัดการการเล่นโฆษณาในแอปของคุณ เมื่อใช้ SDK ฝั่งไคลเอ็นต์ของ IMA คุณจะเป็นผู้ควบคุมการเล่นวิดีโอเนื้อหา ส่วน SDK จะจัดการการเล่นโฆษณา โฆษณาจะเล่นในโปรแกรมเล่นวิดีโอแยกต่างหากซึ่งอยู่ที่ด้านบนของโปรแกรมเล่นวิดีโอเนื้อหาของแอป
คู่มือนี้แสดงวิธีผสานรวม IMA SDK เข้ากับแอปโปรแกรมเล่นวิดีโออย่างง่าย หากคุณต้องการดูหรือทำตามการผสานรวมตัวอย่างที่สมบูรณ์ ให้ดาวน์โหลด BasicExample จาก GitHub
ภาพรวมฝั่งไคลเอ็นต์ของ IMA
การใช้ฝั่งไคลเอ็นต์ของ IMA ประกอบด้วยคอมโพเนนต์ SDK หลัก 4 ส่วน ตามที่แสดงในคู่มือนี้
IMAAdDisplayContainer
: คอนเทนเนอร์ออบเจ็กต์ที่แสดงโฆษณาIMAAdsLoader
: ออบเจ็กต์ที่ขอโฆษณาและจัดการเหตุการณ์จากการตอบกลับคำขอโฆษณา คุณควรยืนยันตัวโหลดโฆษณาเพียง 1 ตัวเท่านั้น ซึ่งสามารถนำมาใช้ซ้ำได้ตลอดอายุของแอปพลิเคชัน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 เป็นผู้จัดการทรัพยากร Dependency สำหรับโปรเจ็กต์ 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.12.0' end
จากไดเรกทอรีที่มี Podfile ให้เรียกใช้
pod install --repo-update
ตรวจสอบว่าการติดตั้งเสร็จสมบูรณ์โดยเปิดไฟล์ BasicExample.xcworkspace และยืนยันว่าไฟล์มี 2 โปรเจ็กต์ ได้แก่ BasicExample และพ็อด (ทรัพยากร Dependency ที่ติดตั้งโดย CocoaPods)
ติดตั้ง SDK โดยใช้ Swift Package Manager
SDK โฆษณาสื่ออินเทอร์แอกทีฟรองรับ Swift Package Manager ตั้งแต่เวอร์ชัน 4.8.2 เป็นต้นไป ทำตามขั้นตอนด้านล่างเพื่อนำเข้าแพ็กเกจ Swift
ใน Xcode ให้ติดตั้ง IMA SDK Swift Package โดยไปที่ 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 จะแก้ไขทรัพยากร Dependency ของแพ็กเกจ และดาวน์โหลดในเบื้องหลัง ดูรายละเอียดเพิ่มเติมเกี่ยวกับวิธีเพิ่มทรัพยากร Dependency ของแพ็กเกจได้ที่บทความของ 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 ทราบว่าเนื้อหาเล่นจบเมื่อใดเพื่อให้แสดงโฆษณาตอนท้ายได้ ซึ่งทำได้ด้วยการโทร 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
ไว้เพียง 1 อินสแตนซ์ตลอดอายุของแอป หากต้องการสร้างคำขอโฆษณาเพิ่มเติม ให้สร้างออบเจ็กต์ 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
จากนั้นให้เริ่มต้นตัวจัดการโฆษณา ซึ่งจะโหลดโฆษณาแต่ละรายการ ตามที่กำหนดโดยการตอบกลับ 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. ตั้งค่าผู้รับมอบสิทธิ์ของผู้จัดการโฆษณา
และสุดท้าย หากต้องการจัดการเหตุการณ์และการเปลี่ยนแปลงสถานะ ผู้จัดการโฆษณาต้องมีผู้รับมอบสิทธิ์ของตนเอง 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() }
การทริกเกอร์เหตุการณ์เล่นและหยุดชั่วคราว
วิธีการมอบสิทธิ์ 2 วิธีสุดท้ายที่คุณต้องใช้งานจะใช้เพื่อทริกเกอร์การเล่นและหยุดเหตุการณ์ชั่วคราวในเนื้อหาวิดีโอที่เกี่ยวข้อง เมื่อ 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