Bắt đầu

IMA SDK giúp bạn dễ dàng tích hợp quảng cáo đa phương tiện vào trang web và ứng dụng của mình. SDK IMA có thể yêu cầu quảng cáo từ bất kỳ máy chủ quảng cáo tuân thủ VAST nào và quản lý việc phát quảng cáo trong ứng dụng của bạn. Với SDK phía máy khách IMA, bạn duy trì quyền kiểm soát việc phát video nội dung, trong khi SDK xử lý việc phát quảng cáo. Quảng cáo phát trong một trình phát video riêng biệt nằm phía trên trình phát video nội dung của ứng dụng.

Hướng dẫn này minh hoạ cách tích hợp SDK IMA vào một ứng dụng trình phát video đơn giản. Nếu bạn muốn xem hoặc làm theo quá trình tích hợp mẫu hoàn chỉnh, hãy tải BasicExample xuống từ GitHub.

Tổng quan phía máy khách IMA

Việc triển khai phía máy khách IMA liên quan đến 4 thành phần SDK chính, được minh hoạ trong hướng dẫn này:

  • IMAAdDisplayContainer: Đối tượng vùng chứa nơi quảng cáo hiển thị.
  • IMAAdsLoader: Đối tượng yêu cầu quảng cáo và xử lý sự kiện từ phản hồi yêu cầu quảng cáo. Bạn chỉ nên tạo thực thể cho một trình tải quảng cáo. Bạn có thể sử dụng lại trình tải này trong suốt thời gian hoạt động của ứng dụng.
  • IMAAdsRequest: Đối tượng xác định yêu cầu quảng cáo. Yêu cầu quảng cáo chỉ định URL cho thẻ quảng cáo VAST, cũng như các thông số bổ sung, chẳng hạn như kích thước quảng cáo.
  • IMAAdsManager: Đối tượng chứa phản hồi cho yêu cầu quảng cáo, kiểm soát việc phát quảng cáo và theo dõi các sự kiện quảng cáo do SDK kích hoạt.

Điều kiện tiên quyết

Trước khi bắt đầu, bạn cần có:

  • Xcode 13 trở lên
  • CocoaPods (ưu tiên), Trình quản lý gói Swift hoặc bản sao đã tải xuống của SDK IMA cho iOS

1. Tạo một dự án Xcode mới

Trong Xcode, hãy tạo một dự án iOS mới bằng Objective-C hoặc Swift. Sử dụng BasicExample làm tên dự án.

2. Thêm SDK IMA vào dự án Xcode

CocoaPods là trình quản lý phần phụ thuộc cho các dự án Xcode và là phương thức nên dùng để cài đặt SDK IMA. Để biết thêm thông tin về cách cài đặt hoặc sử dụng CocoaPods, hãy xem tài liệu về CocoaPods. Sau khi bạn cài đặt CocoaPods, hãy làm theo các hướng dẫn sau để cài đặt SDK IMA:

  1. Trong cùng thư mục với tệp BasicExample.xcodeproj, hãy tạo một tệp văn bản có tên Podfile và thêm cấu hình sau:

    source 'https://github.com/CocoaPods/Specs.git'
    platform :ios, '14'
    target "BasicExample" do
      pod 'GoogleAds-IMA-iOS-SDK', '~> 3.20.0'
    end
    
  2. Trong thư mục chứa Podfile, hãy chạy pod install --repo-update

  3. Xác minh rằng quá trình cài đặt đã thành công bằng cách mở tệp BasicExample.xcworkspace và xác nhận rằng tệp đó chứa 2 dự án: BasicExamplePods (những phần phụ thuộc do CocoaPods cài đặt).

Cài đặt SDK bằng Trình quản lý gói Swift

SDK quảng cáo trên phương tiện truyền thông tương tác hỗ trợ Trình quản lý gói Swift kể từ phiên bản 3.18.4. Hãy làm theo các bước dưới đây để nhập gói Swift.

  1. Trong Xcode, hãy cài đặt Gói Swift SDK IMA bằng cách chuyển đến File > Add Packages... (Tệp > Thêm gói).

  2. Khi lời nhắc xuất hiện, hãy tìm kiếm kho lưu trữ GitHub của IMA SDK Swift Package:

    https://github.com/googleads/swift-package-manager-google-interactive-media-ads-ios
    
  3. Chọn phiên bản của Gói Swift SDK IMA mà bạn muốn sử dụng. Đối với các dự án mới, bạn nên sử dụng tính năng Lên đến phiên bản lớn tiếp theo.

Sau khi bạn hoàn tất, Xcode sẽ giải quyết các phần phụ thuộc của gói và tải các phần phụ thuộc đó xuống trong nền. Để biết thêm thông tin chi tiết về cách thêm các phần phụ thuộc của gói, hãy xem bài viết của Apple.

Tải xuống và cài đặt SDK theo cách thủ công

Nếu không muốn sử dụng Trình quản lý gói Swift hoặc CocoaPods, bạn có thể tải SDK IMA xuống và tự thêm SDK này vào dự án của mình.

3. Tạo một trình phát video đơn giản

Trước tiên, hãy triển khai một trình phát video cơ bản. Ban đầu, trình phát này không sử dụng SDK IMA và không chứa bất kỳ phương thức nào để kích hoạt việc phát.

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. Nhập SDK IMA

Tiếp theo, hãy thêm khung IMA bằng cách sử dụng câu lệnh nhập bên dưới các mục nhập hiện có.

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. Triển khai công cụ theo dõi con trỏ vị trí phát nội dung và trình quan sát cuối luồng

Để phát quảng cáo trong video, SDK IMA cần theo dõi vị trí hiện tại của nội dung video. Để thực hiện việc này, hãy tạo một lớp triển khai IMAContentPlayhead. Nếu bạn đang sử dụng AVPlayer, như trong ví dụ này, SDK sẽ cung cấp lớp IMAAVPlayerContentPlayhead để thực hiện việc này cho bạn. Nếu không sử dụng AVPlayer, bạn cần triển khai IMAContentPlayhead trên một lớp của riêng mình.

Bạn cũng cần cho SDK biết khi nào nội dung của bạn đã phát xong để nó có thể hiển thị quảng cáo sau video. Bạn có thể thực hiện việc này bằng cách gọi contentComplete trên IMAAdsLoader thông qua 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. Khởi động trình tải quảng cáo và đưa ra một yêu cầu quảng cáo

Để yêu cầu một nhóm quảng cáo, bạn cần tạo một phiên bản IMAAdsLoader. Bạn có thể dùng trình tải này để xử lý các đối tượng IMAAdsRequest liên kết với URL thẻ quảng cáo đã chỉ định.

Cách tốt nhất là chỉ duy trì một phiên bản của IMAAdsLoader trong toàn bộ vòng đời của ứng dụng. Để thực hiện thêm yêu cầu quảng cáo, hãy tạo một đối tượng IMAAdsRequest mới, nhưng sử dụng lại cùng một IMAAdsLoader. Để biết thêm thông tin, hãy xem bài viết Câu hỏi thường gặp về SDK IMA.

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

  @objc func contentDidFinishPlaying(_ notification: Notification) {
    adsLoader.contentComplete()
  }
}
      

7. Thiết lập thực thể đại diện cho trình tải quảng cáo

Trong sự kiện tải thành công, IMAAdsLoader sẽ gọi phương thức adsLoadedWithData của đại biểu đã chỉ định, truyền vào đó một thực thể của IMAAdsManager. Sau đó, bạn có thể khởi chạy trình quản lý quảng cáo để tải từng quảng cáo riêng lẻ, như được xác định bằng phản hồi cho URL thẻ quảng cáo.

Ngoài ra, hãy nhớ xử lý mọi lỗi có thể xảy ra trong quá trình tải. Nếu quảng cáo không tải, hãy đảm bảo rằng nội dung nghe nhìn sẽ tiếp tục phát mà không có quảng cáo, để không ảnh hưởng đến trải nghiệm của người dùng.

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. Thiết lập người được uỷ quyền trong tài khoản người quản lý quảng cáo

Cuối cùng, để quản lý các sự kiện và thay đổi trạng thái, trình quản lý quảng cáo cần được ủy quyền của riêng mình. IMAAdManagerDelegate có các phương thức để xử lý các lỗi và sự kiện quảng cáo, cũng như các phương thức để kích hoạt việc phát và tạm dừng nội dung video của bạn.

Đang bắt đầu phát

Có nhiều sự kiện mà phương thức didReceiveAdEvent có thể được sử dụng để xử lý, nhưng đối với ví dụ cơ bản này, bạn chỉ cần theo dõi sự kiện LOADED để yêu cầu trình quản lý quảng cáo bắt đầu phát nội dung và quảng cáo.

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

...
      

Xử lý lỗi

Ngoài ra, hãy thêm một trình xử lý cho các lỗi quảng cáo. Nếu xảy ra lỗi, như trong bước trước, hãy tiếp tục phát nội dung.

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

Kích hoạt các sự kiện phát và tạm dừng

Hai phương thức uỷ quyền cuối cùng bạn cần triển khai được dùng để kích hoạt các sự kiện phát và tạm dừng trên nội dung video cơ bản khi được SDK IMA yêu cầu. Việc kích hoạt tính năng tạm dừng và phát khi được yêu cầu sẽ ngăn người dùng bỏ lỡ các phần của nội dung video khi quảng cáo hiển thị.

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

Vậy là xong! Bạn hiện đang yêu cầu và hiển thị quảng cáo bằng SDK IMA. Để tìm hiểu về các tính năng SDK bổ sung, hãy xem hướng dẫn khác hoặc mẫu trên GitHub.

Các bước tiếp theo

Để tối đa hoá doanh thu từ quảng cáo trên nền tảng iOS, hãy yêu cầu Tính minh bạch của ứng dụng và Quyền theo dõi để sử dụng IDFA.