IMA SDK を使用すると、マルチメディア広告をウェブサイトやアプリに簡単に統合できます。IMA SDK は、 VAST 準拠のあらゆる広告サーバーから広告をリクエストし、アプリでの広告再生を管理できます。IMA クライアントサイド SDK を使用すると、コンテンツ動画の再生を制御しながら、SDK で広告の再生を処理できます。広告は、アプリのコンテンツ動画プレーヤーの上に配置された別の動画プレーヤーで再生されます。
このガイドでは、IMA SDK を動画プレーヤー アプリに統合する方法について説明します。完成したサンプル統合を表示または実行する場合は、GitHub から BasicExample をダウンロードしてください。
IMA クライアントサイドの概要
IMA クライアントサイドの実装には、このガイドで説明する 4 つの主要な SDK コンポーネントが含まれます。
IMAAdDisplayContainer
: IMA が広告の UI 要素をレンダリングし、アクティブ ビューやオープン測定などの視認性を測定する場所を指定するコンテナ オブジェクト。IMAAdsLoader
: 広告をリクエストし、広告リクエスト レスポンスからのイベントを処理するオブジェクト。広告ローダは 1 つだけインスタンス化し、アプリのライフサイクル全体で再利用する必要があります。IMAAdsRequest
: 広告リクエストを定義するオブジェクト。広告リクエストでは、VAST 広告タグの URL と、広告のサイズなどの追加パラメータを指定します。IMAAdsManager
: 広告リクエストに対するレスポンスを含み、広告の再生を制御し、SDK によって発生した広告イベントをリッスンするオブジェクト。
前提条件
始める前に、次のものが必要になります。
- Xcode 13 以降
- CocoaPods(推奨)、Swift Package Manager、または IMA SDK for iOS のダウンロード済みコピー
1. 新しい Xcode プロジェクトを作成する
Xcode で、Objective-C または Swift を使用して新しい iOS プロジェクトを作成します。プロジェクト名として BasicExample を使用します。
2. Xcode プロジェクトに IMA SDK を追加する
CocoaPods を使用して SDK をインストールする(推奨)
CocoaPods は Xcode プロジェクトの依存関係マネージャーであり、IMA SDK をインストールする推奨の方法です。CocoaPods のインストールと使用について詳しくは、CocoaPods のドキュメントをご覧ください。CocoaPods をインストールしたら、次の手順で IMA SDK をインストールします。
BasicExample.xcodeproj ファイルと同じディレクトリに、Podfile という名前のテキスト ファイルを作成し、次の構成を追加します。
Objective-C
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '12' target "BasicExample" do pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1' end
Swift
source 'https://github.com/CocoaPods/Specs.git' platform :ios, '12' target "BasicExample" do pod 'GoogleAds-IMA-iOS-SDK', '~> 3.26.1' end
Podfile が含まれているディレクトリから、
pod install --repo-update
を実行します。BasicExample.xcworkspace ファイルを開き、BasicExample と Pods(CocoaPods によってインストールされた依存関係)の 2 つのプロジェクトが含まれていることを確認して、インストールが成功したことを確認します。
Swift Package Manager を使用して SDK をインストールする
インタラクティブ メディア広告 SDK はバージョン 3.18.4 から Swift Package Manager に対応しています。Swift パッケージをインポートする手順は次のとおりです。
Xcode で File > Add Package Dependencies... を開き、IMA SDK の Swift パッケージをインストールします。
プロンプトで、IMA iOS SDK Swift パッケージの GitHub リポジトリ(
swift-package-manager-google-interactive-media-ads-ios
)を検索します。使用する IMA SDK Swift パッケージのバージョンを選択します。新しいプロジェクトの場合は [Up to Next Major Version] を選択することをおすすめします。
完了すると、Xcode はパッケージの依存関係を解決し、バックグラウンドでダウンロードします。パッケージの依存関係の追加について詳しくは、Apple の記事を参照してください。
SDK を手動でダウンロードしてインストールする
Swift Package Manager または CocoaPods を使用しない場合は、IMA SDK をダウンロードして、プロジェクトに手動で追加できます。
3. 動画プレーヤーを作成する
まず、動画プレーヤーを実装します。このプレーヤーは、最初は IMA SDK を使用せず、再生をトリガーするメソッドも含まれていません。
Objective-C
プレーヤーの依存関係をインポートします。
#import "ViewController.h"
@import AVFoundation;
プレーヤー変数を設定します。
@interface ViewController () <IMAAdsLoaderDelegate, IMAAdsManagerDelegate>
/// Content video player.
@property(nonatomic, strong) AVPlayer *contentPlayer;
/// Play button.
@property(nonatomic, weak) IBOutlet UIButton *playButton;
/// UIView in which we will render our AVPlayer for content.
@property(nonatomic, weak) IBOutlet UIView *videoView;
ビューの読み込み時に動画プレーヤーを初期化します。
@implementation ViewController
// The content URL to play.
NSString *const kTestAppContentUrl_MP4 =
@"https://storage.googleapis.com/gvabox/media/samples/stock.mp4";
// Ad tag
NSString *const kTestAppAdTagUrl = @"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=";
- (void)viewDidLoad {
[super viewDidLoad];
self.playButton.layer.zPosition = MAXFLOAT;
[self setupAdsLoader];
[self setUpContentPlayer];
}
#pragma mark Content Player Setup
- (void)setUpContentPlayer {
// Load AVPlayer with path to our content.
NSURL *contentURL = [NSURL URLWithString:kTestAppContentUrl_MP4];
self.contentPlayer = [AVPlayer playerWithURL:contentURL];
// Create a player layer for the player.
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.contentPlayer];
// Size, position, and display the AVPlayer.
playerLayer.frame = self.videoView.layer.bounds;
[self.videoView.layer addSublayer:playerLayer];
// Set up our content playhead and contentComplete callback.
self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentDidFinishPlaying:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.contentPlayer.currentItem];
}
- (IBAction)onPlayButtonTouch:(id)sender {
[self requestAds];
self.playButton.hidden = YES;
}
Swift
プレーヤーの依存関係をインポートします。
import AVFoundation
プレーヤー変数を設定します。
class PlayerContainerViewController: UIViewController, IMAAdsLoaderDelegate, IMAAdsManagerDelegate {
static let contentURL = URL(
string: "https://storage.googleapis.com/gvabox/media/samples/stock.mp4")!
private var contentPlayer = AVPlayer(url: PlayerContainerViewController.contentURL)
private lazy var playerLayer: AVPlayerLayer = {
AVPlayerLayer(player: contentPlayer)
}()
ビューの読み込み時に動画プレーヤーを初期化します。
private lazy var videoView: UIView = {
let videoView = UIView()
videoView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(videoView)
NSLayoutConstraint.activate([
videoView.bottomAnchor.constraint(
equalTo: view.safeAreaLayoutGuide.bottomAnchor),
videoView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
videoView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
videoView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
])
return videoView
}()
// MARK: - View controller lifecycle methods
override func viewDidLoad() {
super.viewDidLoad()
videoView.layer.addSublayer(playerLayer)
adsLoader.delegate = self
NotificationCenter.default.addObserver(
self,
selector: #selector(contentDidFinishPlaying(_:)),
name: .AVPlayerItemDidPlayToEndTime,
object: contentPlayer.currentItem)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
playerLayer.frame = videoView.layer.bounds
}
override func viewWillTransition(
to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator
) {
coordinator.animate { _ in
// do nothing
} completion: { _ in
self.playerLayer.frame = self.videoView.layer.bounds
}
}
// MARK: - Public methods
func playButtonPressed() {
requestAds()
}
4. IMA SDK をインポートする
IMA SDK をインポートする手順は次のとおりです。
Objective-C
IMA SDK をインポートします。
@import GoogleInteractiveMediaAds;
アプリで使用される
IMAAdsLoader
、IMAAVPlayerContentPlayhead
、IMAAdsManager
クラスの変数を作成します。// SDK /// Entry point for the SDK. Used to make ad requests. @property(nonatomic, strong) IMAAdsLoader *adsLoader; /// Playhead used by the SDK to track content video progress and insert mid-rolls. @property(nonatomic, strong) IMAAVPlayerContentPlayhead *contentPlayhead; /// Main point of interaction with the SDK. Created by the SDK as the result of an ad request. @property(nonatomic, strong) IMAAdsManager *adsManager;
Swift
IMA SDK をインポートします。
import GoogleInteractiveMediaAds
アプリで使用される
IMAAdsLoader
、IMAAVPlayerContentPlayhead
、IMAAdsManager
クラスの変数を作成します。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=" private let adsLoader = IMAAdsLoader() private var adsManager: IMAAdsManager? private lazy var contentPlayhead: IMAAVPlayerContentPlayhead = { IMAAVPlayerContentPlayhead(avPlayer: contentPlayer) }()
5. コンテンツの再生ヘッド トラッカーとストリーム終了オブザーバーを実装する
ミッドロール広告を再生するには、IMA SDK で動画コンテンツの現在の位置をトラッキングする必要があります。そのためには、IMAContentPlayhead
を実装するクラスを作成します。この例に示すように AVPlayer
を使用している場合、SDK はこの処理を行う IMAAVPlayerContentPlayhead
クラスを提供します。AVPlayer
を使用していない場合は、独自のクラスに IMAContentPlayhead
を実装する必要があります。
また、コンテンツの再生が終了したタイミングを SDK に通知して、ポストロール広告を表示できるようにする必要があります。これを行うには、AVPlayerItemDidPlayToEndTimeNotification
を使用して IMAAdsLoader で contentComplete
メソッドを呼び出します。
Objective-C
プレーヤーのセットアップで IMAAVPlayerContentPlayhead
インスタンスを作成します。
// Set up our content playhead and contentComplete callback.
self.contentPlayhead = [[IMAAVPlayerContentPlayhead alloc] initWithAVPlayer:self.contentPlayer];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contentDidFinishPlaying:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:self.contentPlayer.currentItem];
コンテンツの再生が終了したときに IMAAdsLoader.contentComplete()
を呼び出す contentDidFinishPlaying()
メソッドを作成します。
- (void)contentDidFinishPlaying:(NSNotification *)notification {
// Make sure we don't call contentComplete as a result of an ad completing.
if (notification.object == self.contentPlayer.currentItem) {
[self.adsLoader contentComplete];
}
}
Swift
プレーヤーの設定でコンテンツ終了オブザーバーを作成します。
NotificationCenter.default.addObserver(
self,
selector: #selector(contentDidFinishPlaying(_:)),
name: .AVPlayerItemDidPlayToEndTime,
object: contentPlayer.currentItem)
コンテンツの再生が終了したときに IMAAdsLoader.contentComplete()
を呼び出す contentDidFinishPlaying()
メソッドを作成します。
@objc func contentDidFinishPlaying(_ notification: Notification) {
// Make sure we don't call contentComplete as a result of an ad completing.
if notification.object as? AVPlayerItem == contentPlayer.currentItem {
adsLoader.contentComplete()
}
}
6. 広告ローダを初期化して広告リクエストを行う
広告セットをリクエストするには、IMAAdsLoader
インスタンスを作成する必要があります。このローダーは、指定された広告タグ URL に関連付けられた IMAAdsRequest
オブジェクトを処理するために使用できます。
ベスト プラクティスとして、アプリのライフサイクル全体で IMAAdsLoader
のインスタンスを 1 つだけ維持します。追加の広告リクエストを行うには、新しい IMAAdsRequest
オブジェクトを作成しますが、同じ IMAAdsLoader
を再利用します。詳しくは、IMA SDK のよくある質問をご覧ください。
Objective-C
- (void)setupAdsLoader {
self.adsLoader = [[IMAAdsLoader alloc] initWithSettings:nil];
self.adsLoader.delegate = self;
}
- (void)requestAds {
// Create an ad display container for ad rendering.
IMAAdDisplayContainer *adDisplayContainer =
[[IMAAdDisplayContainer alloc] initWithAdContainer:self.videoView
viewController:self
companionSlots:nil];
// Create an ad request with our ad tag, display container, and optional user context.
IMAAdsRequest *request = [[IMAAdsRequest alloc] initWithAdTagUrl:kTestAppAdTagUrl
adDisplayContainer:adDisplayContainer
contentPlayhead:self.contentPlayhead
userContext:nil];
[self.adsLoader requestAdsWithRequest:request];
}
Swift
private func requestAds() {
// Create ad display container for ad rendering.
let adDisplayContainer = IMAAdDisplayContainer(
adContainer: videoView, viewController: self, companionSlots: nil)
// Create an ad request with our ad tag, display container, and optional user context.
let request = IMAAdsRequest(
adTagUrl: PlayerContainerViewController.adTagURLString,
adDisplayContainer: adDisplayContainer,
contentPlayhead: contentPlayhead,
userContext: nil)
adsLoader.requestAds(with: request)
}
7. 広告ローダのデリゲートを設定する
読み込みイベントが成功すると、IMAAdsLoader
は割り当てられたデリゲートの adsLoadedWithData
メソッドを呼び出し、IMAAdsManager
のインスタンスを渡します。その後、広告タグ URL のレスポンスで定義された個々の広告を読み込む広告マネージャーを初期化できます。
また、読み込みプロセス中に発生する可能性のあるエラーを処理してください。広告が読み込まれない場合は、ユーザー エクスペリエンスを妨げないように、広告なしでメディアの再生が継続されるようにしてください。
Objective-C
- (void)adsLoader:(IMAAdsLoader *)loader adsLoadedWithData:(IMAAdsLoadedData *)adsLoadedData {
// Grab the instance of the IMAAdsManager and set ourselves as the delegate.
self.adsManager = adsLoadedData.adsManager;
self.adsManager.delegate = self;
// Create ads rendering settings to tell the SDK to use the in-app browser.
IMAAdsRenderingSettings *adsRenderingSettings = [[IMAAdsRenderingSettings alloc] init];
adsRenderingSettings.linkOpenerPresentingController = self;
// Initialize the ads manager.
[self.adsManager initializeWithAdsRenderingSettings:adsRenderingSettings];
}
- (void)adsLoader:(IMAAdsLoader *)loader failedWithErrorData:(IMAAdLoadingErrorData *)adErrorData {
// Something went wrong loading ads. Log the error and play the content.
NSLog(@"Error loading ads: %@", adErrorData.adError.message);
[self.contentPlayer 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
// Create ads rendering settings and tell the SDK to use the in-app browser.
let adsRenderingSettings = IMAAdsRenderingSettings()
adsRenderingSettings.linkOpenerPresentingController = self
// Initialize the ads manager.
adsManager?.initialize(with: adsRenderingSettings)
}
func adsLoader(_ loader: IMAAdsLoader, failedWith adErrorData: IMAAdLoadingErrorData) {
if let message = adErrorData.adError.message {
print("Error loading ads: \(message)")
}
contentPlayer.play()
}
8. 広告マネージャーの代理人を設定する
最後に、イベントと状態の変化を管理するために、広告マネージャーには独自のデリゲートが必要です。IMAAdManagerDelegate
には、広告イベントとエラーを処理するメソッドと、動画コンテンツの再生と一時停止をトリガーするメソッドがあります。
再生を開始
LOADED
イベントをリッスンして、コンテンツと広告の再生を開始します。詳しくは、didReceiveAdEvent
をご覧ください。
Objective-C
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdEvent:(IMAAdEvent *)event {
// When the SDK notified us that ads have been loaded, play them.
if (event.type == kIMAAdEvent_LOADED) {
[adsManager start];
}
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive event: IMAAdEvent) {
// When the SDK notifies us the ads have been loaded, play them.
if event.type == IMAAdEventType.LOADED {
adsManager.start()
}
}
エラーを処理する
広告エラーのハンドラも追加します。前の手順と同様にエラーが発生した場合は、コンテンツの再生を再開します。
Objective-C
- (void)adsManager:(IMAAdsManager *)adsManager didReceiveAdError:(IMAAdError *)error {
// Something went wrong with the ads manager after ads were loaded. Log the error and play the
// content.
NSLog(@"AdsManager error: %@", error.message);
[self.contentPlayer play];
}
Swift
func adsManager(_ adsManager: IMAAdsManager, didReceive error: IMAAdError) {
// Something went wrong with the ads manager after ads were loaded.
// Log the error and play the content.
if let message = error.message {
print("AdsManager error: \(message)")
}
contentPlayer.play()
}
再生イベントと一時停止イベントをリッスンする
実装する必要がある最後の 2 つのデリゲート メソッドは、IMA SDK からリクエストされたときに、基盤となる動画コンテンツの再生イベントと一時停止イベントをトリガーするために使用されます。リクエストに応じて一時停止と再生をトリガーすることで、広告が表示されたときにユーザーが動画コンテンツの一部を見逃すのを防ぎます。
Objective-C
- (void)adsManagerDidRequestContentPause:(IMAAdsManager *)adsManager {
// The SDK is going to play ads, so pause the content.
[self.contentPlayer pause];
}
- (void)adsManagerDidRequestContentResume:(IMAAdsManager *)adsManager {
// The SDK is done playing ads (at least for now), so resume the content.
[self.contentPlayer play];
}
Swift
func adsManagerDidRequestContentPause(_ adsManager: IMAAdsManager) {
// The SDK is going to play ads, so pause the content.
contentPlayer.pause()
}
func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) {
// The SDK is done playing ads (at least for now), so resume the content.
contentPlayer.play()
}
これで、これで、IMA SDK を使用して広告をリクエストし、表示できるようになりました。その他の SDK 機能については、他のガイドまたは GitHub のサンプルをご覧ください。
次のステップ
iOS プラットフォームで広告収益を最大化するには、IDFA を使用するための App Transparency and Tracking の許可をリクエストします。