Rozpocznij

Pakiety IMA SDK ułatwiają integrację reklam multimedialnych z witrynami i aplikacjami. Pakiety IMA SDK mogą żądać reklam z dowolnego serwera reklam zgodnego z VAST i zarządzać odtwarzaniem reklam w aplikacjach. Dzięki pakietom SDK IMA po stronie klienta możesz kontrolować odtwarzanie treści wideo, a pakiet SDK obsługuje odtwarzanie reklam. Reklamy są wyświetlane w oddzielnym odtwarzaczu wideo umieszczonym nad odtwarzaczem treści aplikacji.

Ten przewodnik pokazuje, jak zintegrować pakiet IMA SDK z prostym odtwarzaczem wideo. Jeśli chcesz zobaczyć lub prześledzić przykładową integrację, pobierz BasicExample z GitHuba.

IMA po stronie klienta

Implementacja IMA po stronie klienta obejmuje 4 główne komponenty pakietu SDK, które są opisane w tym przewodniku:

  • IMAAdDisplayContainer: obiekt kontenera, w którym renderowane są reklamy.
  • IMAAdsLoader: obiekt, który wysyła żądania reklam i obsługuje zdarzenia z odpowiedzi na żądania reklam. Powinieneś utworzyć tylko 1 instans loadera reklam, który można używać wielokrotnie przez cały czas działania aplikacji.
  • IMAAdsRequest: obiekt definiujący żądanie reklamy. Żądania reklamy określają adres URL tagu reklamy VAST oraz dodatkowe parametry, takie jak wymiary reklamy.
  • IMAAdsManager: obiekt zawierający odpowiedź na żądanie reklamy, który kontroluje odtwarzanie reklam i odbiera zdarzenia reklamowe wywołane przez pakiet SDK.

Wymagania wstępne

Zanim zaczniesz, musisz mieć:

1. Tworzenie nowego projektu Xcode

W Xcode utwórz nowy projekt tvOS w języku Objective-C lub Swift. Jako nazwę projektu użyj BasicExample.

2. Dodawanie pakietu IMA SDK do projektu Xcode

Instalowanie pakietu SDK za pomocą CocoaPods (preferowane)

CocoaPods to menedżer zależności dla projektów Xcode i zalecana metoda instalowania pakietu IMA SDK. Więcej informacji o instalowaniu i używaniu CocoaPods znajdziesz w dokumentacji CocoaPods. Po zainstalowaniu CocoaPods wykonaj te instrukcje, aby zainstalować pakiet IMA SDK:

  1. W tym samym katalogu, w którym znajduje się plik BasicExample.xcodeproj, utwórz plik tekstowy o nazwie Podfile i dodaj tę konfigurację:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :tvos, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-tvOS-SDK', '~> 4.13.0'
    end
    
  2. W katalogu, który zawiera plik Podfile, uruchom pod install --repo-update

  3. Aby sprawdzić, czy instalacja przebiegła pomyślnie, otwórz plik BasicExample.xcworkspace i sprawdź, czy zawiera on 2 projekty: BasicExamplePods (zależność zainstalowana przez CocoaPods).

Instalowanie pakietu SDK za pomocą menedżera pakietów Swift

Pakiet SDK do wyświetlania interaktywnych reklam medialnych obsługuje Swift Package Manager od wersji 4.8.2. Aby zaimportować pakiet Swift, wykonaj czynności opisane poniżej.

  1. W Xcode zainstaluj pakiet IMA SDK Swift, klikając Plik > Dodaj pakiety....

  2. W wyświetlonym promptzie wyszukaj repozytorium GitHub pakietu IMA SDK Swift Package:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-tvos
    
  3. Wybierz wersję pakietu IMA SDK Swift, której chcesz użyć. W przypadku nowych projektów zalecamy używanie wersji aż do następnej wersji głównej.

Gdy skończysz, Xcode zweryfikuje zależności pakietu i pobierze je w tle. Więcej informacji o dodawaniu zależności pakietu znajdziesz w artykule Apple.

Ręczne pobieranie i instalowanie pakietu SDK

Jeśli nie chcesz używać CocoaPods, możesz pobrać pakiet IMA SDK i dodać go ręcznie do swojego projektu.

3. Tworzenie prostego odtwarzacza wideo

Najpierw wprowadź podstawowy odtwarzacz filmów. Początkowo odtwarzacz nie korzysta z pakietu IMA SDK i nie zawiera jeszcze żadnej metody wywołania odtwarzania.

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. Importowanie pakietu IMA SDK

Następnie dodaj ramy IMA, używając instrukcji importu pod istniejącymi importami.

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. Wdrożenie śledzenia odtwarzania treści i obserwatora końca strumienia

Aby wyświetlać reklamy w trakcie filmu, pakiet IMA SDK musi śledzić bieżącą pozycję treści wideo. Aby to zrobić, utwórz klasę, która implementuje interfejs IMAContentPlayhead. Jeśli używasz AVPlayer, jak w tym przykładzie, pakiet SDK udostępnia klasę IMAAVPlayerContentPlayhead, która wykonuje tę czynność. Jeśli nie używasz AVPlayer, musisz zaimplementować IMAContentPlayhead na własnych zajęciach.

Musisz też poinformować pakiet SDK, kiedy kończy się odtwarzanie treści, aby mógł wyświetlić reklamy po zakończeniu filmu. Aby to zrobić, wywołaj funkcję contentComplete w obiekcie IMAAdsLoader, używając funkcji 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. Inicjowanie ładowarki reklam i wysyłanie żądania reklamy

Aby poprosić o zestaw reklam, musisz utworzyć instancję IMAAdsLoader. Za jego pomocą można przetworzyć obiekty IMAAdsRequest powiązane z określonym adresem URL tagu reklamy.

Zalecamy utrzymywanie tylko 1 instancji IMAAdsLoader przez cały cykl życia aplikacji. Aby wysyłać dodatkowe żądania reklam, utwórz nowy obiekt IMAAdsRequest, ale używaj tego samego obiektu IMAAdsLoader. Więcej informacji znajdziesz w odpowiedziach na najczęstsze pytania dotyczące pakietu 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. Konfigurowanie delegata ładowarki reklam

Po udanym zdarzeniu wczytywania IMAAdsLoader wywołuje metodę adsLoadedWithData przypisanego przedstawiciela, przekazując mu instancję IMAAdsManager. Następnie możesz zainicjować menedżera reklam, który wczytuje poszczególne reklamy zgodnie z definicją w odpowiedzi na adres URL tagu reklamy.

Pamiętaj też, aby obsłużyć wszelkie błędy, które mogą wystąpić podczas procesu wczytywania. Jeśli reklamy się nie ładują, upewnij się, że odtwarzanie multimediów jest kontynuowane bez reklam, aby nie zakłócać korzystania z aplikacji.

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. Konfigurowanie delegata w usłudze Ad Manager

Na koniec: aby zarządzać zdarzeniami i zmianami stanu, menedżer reklam musi mieć swojego własnego przedstawiciela. IMAAdManagerDelegate zawiera metody do obsługi błędów i zdarzeń związanych z reklamami, a także metody uruchamiania odtwarzania i wstrzymywania treści wideo.

Rozpoczynam odtwarzanie

Metoda didReceiveAdEvent może obsługiwać wiele zdarzeń, ale w tym podstawowym przykładzie wystarczy wychwycić zdarzenie LOADED, aby poinformować menedżera reklam o rozpoczęciu odtwarzania treści i reklam.

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()
    }
  }

...
      

Obsługa błędów

Dodaj też moduł obsługi błędów reklam. Jeśli wystąpi błąd, wznów odtwarzanie treści tak jak w poprzednim kroku.

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()
  }
      

Aktywowanie zdarzeń odtwarzania i wstrzymywania

Ostatnie 2 metody delegowane, które musisz zaimplementować, służą do uruchamiania zdarzeń odtwarzania i wstrzymywania w treści wideo, gdy pakiet IMA SDK wysyła odpowiednią prośbę. Wstrzymywanie i odtwarzanie filmu na żądanie zapobiega pomijaniu przez użytkownika części treści wideo podczas wyświetlania reklam.

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()
  }
}
      

Znakomicie. Zamawiasz i wyświetlasz reklamy za pomocą pakietu IMA SDK. Aby dowiedzieć się więcej o dodatkowych funkcjach pakietu SDK, zapoznaj się z innymi przewodnikami lub przykładami na GitHubie.

Następne kroki

Aby zmaksymalizować przychody z reklam na platformie tvOS, poproś o uprawnienia App Tracking Transparency na potrzeby korzystania z IDFA.