보상형 광고

보상형 광고는 사용자가 인앱 리워드를 받는 대가로 상호작용할 수 있는 광고입니다. 이 가이드에서는 AdMob의 보상형 광고를 iOS 앱에 통합하는 방법을 설명합니다. 고객 성공사례인 우수사례 1우수사례 2를 읽어보세요.

기본 요건

항상 테스트 광고로 테스트

앱을 빌드하고 테스트할 때는 운영 중인 실제 광고 대신 테스트 광고를 사용하세요. 이렇게 하지 않으면 계정이 정지될 수 있습니다.

테스트 광고를 로드하는 가장 쉬운 방법은 iOS 보상형 광고의 테스트 전용 광고 단위 ID를 사용하는 것입니다.

ca-app-pub-3940256099942544/1712485313

이 ID는 모든 요청에 대해 테스트 광고를 반환하도록 특별히 구성되었으며, 코딩, 테스트 및 디버깅 중에 앱에서 자유롭게 사용할 수 있습니다. 앱을 게시하기 전에 이 ID를 자체 광고 단위 ID로 바꿔야 합니다.

모바일 광고 SDK의 테스트 광고가 작동하는 방식을 자세히 알아보려면 테스트 광고를 참고하세요.

구현

보상형 광고를 통합하는 기본 단계는 다음과 같습니다.

  • 광고 로드
  • [선택사항] SSV 콜백 확인
  • 콜백 등록
  • 광고 표시 및 보상 이벤트 처리

광고 로드

광고는 GADRewardedAd 클래스의 load(adUnitID:request) 메서드를 사용하여 로드됩니다.

Swift

import GoogleMobileAds
import UIKit

class ViewController: UIViewController {

  private var rewardedAd: GADRewardedAd?

  func loadRewardedAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
    } catch {
      print("Rewarded ad failed to load with error: \(error.localizedDescription)")
    }
  }
}

SwiftUI

import GoogleMobileAds

class RewardedViewModel: NSObject, ObservableObject, GADFullScreenContentDelegate {
  @Published var coins = 0
  private var rewardedAd: GADRewardedAd?

  func loadAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
      rewardedAd?.fullScreenContentDelegate = self
    } catch {
      print("Failed to load rewarded ad with error: \(error.localizedDescription)")
    }
  }

Objective-C

@import GoogleMobileAds;
@import UIKit;

@interface ViewController ()

@property(nonatomic, strong) GADRewardedAd *rewardedAd;

@end

@implementation ViewController
- (void)loadRewardedAd {
  GADRequest *request = [GADRequest request];
  [GADRewardedAd
      loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
                request:request
      completionHandler:^(GADRewardedAd *ad, NSError *error) {
        if (error) {
          NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
          return;
        }
        self.rewardedAd = ad;
        NSLog(@"Rewarded ad loaded.");
      }];
}

[선택사항] 서버 측 확인 (SSV) 콜백 검사

서버 측 확인 콜백에서 추가 데이터가 필요한 앱은 보상형 광고의 맞춤 데이터 기능을 사용해야 합니다. 보상형 광고 객체에 설정된 모든 문자열 값은 SSV 콜백의 custom_data 쿼리 매개변수에 전달됩니다. 맞춤 데이터 값이 설정되지 않은 경우 custom_data 쿼리 매개변수 값은 SSV 콜백에 표시되지 않습니다.

다음 코드 샘플은 광고를 요청하기 전에 보상형 광고 객체에 맞춤 데이터를 설정하는 방법을 보여줍니다.

Swift

do {
  rewardedAd = try await GADRewardedAd.load(
    withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
  let options = GADServerSideVerificationOptions()
  options.customRewardString = "SAMPLE_CUSTOM_DATA_STRING"
  rewardedAd.serverSideVerificationOptions = options
} catch {
  print("Rewarded ad failed to load with error: \(error.localizedDescription)")
}

Objective-C

[GADRewardedAd
     loadWithAdUnitID:@"ca-app-pub-3940256099942544/1712485313"
              request:[GADRequest request];
    completionHandler:^(GADRewardedAd *ad, NSError *error) {
      if (error) {
        // Handle Error
        return;
      }
      self.rewardedAd = ad;
      GADServerSideVerificationOptions *options =
          [[GADServerSideVerificationOptions alloc] init];
      options.customRewardString = @"SAMPLE_CUSTOM_DATA_STRING";
      ad.serverSideVerificationOptions = options;
    }];

콜백 등록

표시 이벤트 알림을 받으려면 GADFullScreenContentDelegate 프로토콜을 구현하고 이를 반환된 광고의 fullScreenContentDelegate 속성에 할당해야 합니다. GADFullScreenContentDelegate 프로토콜은 광고 표시에 성공 또는 실패했을 때와 광고가 닫혔을 때의 콜백을 처리합니다. 다음은 프로토콜을 구현하고 이를 광고에 할당하는 방법을 나타내는 코드입니다.

Swift

import GoogleMobileAds
import UIKit

class ViewController: UIViewController, GADFullScreenContentDelegate {

  private var rewardedAd: GADRewardedAd?

  func loadRewardedAd() async {
    do {
      rewardedAd = try await GADRewardedAd.load(
        withAdUnitID: "ca-app-pub-3940256099942544/1712485313", request: GADRequest())
      rewardedAd?.fullScreenContentDelegate = self
    } catch {
      print("Rewarded ad failed to load with error: \(error.localizedDescription)")
    }
  }

  /// Tells the delegate that the ad failed to present full screen content.
  func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
    print("Ad did fail to present full screen content.")
  }

  /// Tells the delegate that the ad will present full screen content.
  func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    print("Ad will present full screen content.")
  }

  /// Tells the delegate that the ad dismissed full screen content.
  func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
    print("Ad did dismiss full screen content.")
  }
}

SwiftUI

반환된 광고에 fullScreenContentDelegate 속성을 할당합니다.

rewardedAd?.fullScreenContentDelegate = self

프로토콜을 구현합니다.

func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adDidRecordClick(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func ad(
  _ ad: GADFullScreenPresentingAd,
  didFailToPresentFullScreenContentWithError error: Error
) {
  print("\(#function) called")
}

func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
}

func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
  print("\(#function) called")
  // Clear the rewarded ad.
  rewardedAd = nil
}

Objective-C

@interface ViewController () <GADFullScreenContentDelegate>

@property(nonatomic, strong) GADRewardedAd *rewardedAd;

@end

@implementation ViewController
- (void)loadRewardedAd {
  GADRequest *request = [GADRequest request];
  [GADRewardedAd
      loadWithAdUnitID:@"ca-app-pub-3940256099942544/4806952744"
                request:request
      completionHandler:^(GADRewardedAd *ad, NSError *error) {
        if (error) {
          NSLog(@"Rewarded ad failed to load with error: %@", [error localizedDescription]);
          return;
        }
        self.rewardedAd = ad;
        NSLog(@"Rewarded ad loaded.");
        self.rewardedAd.fullScreenContentDelegate = self;
      }];
}

/// Tells the delegate that the ad failed to present full screen content.
- (void)ad:(nonnull id<GADFullScreenPresentingAd>)ad
    didFailToPresentFullScreenContentWithError:(nonnull NSError *)error {
    NSLog(@"Ad did fail to present full screen content.");
}

/// Tells the delegate that the ad will present full screen content.
- (void)adWillPresentFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
    NSLog(@"Ad will present full screen content.");
}

/// Tells the delegate that the ad dismissed full screen content.
- (void)adDidDismissFullScreenContent:(nonnull id<GADFullScreenPresentingAd>)ad {
    NSLog(@"Ad did dismiss full screen content.");
}

GADRewardedAd는 일회용 객체입니다. 즉, 보상형 광고가 표시된 후에는 다시 표시되지 않습니다. 이전 광고가 닫히자마자 다음 보상형 광고가 로드될 수 있도록 adDidDismissFullScreenContent: 메서드로 GADFullScreenContentDelegate에 다른 보상형 광고를 로드하는 것이 좋습니다.

광고 표시 및 보상 이벤트 처리

보상형 광고를 게재하기 전에 보상을 받는 대가로 보상형 광고 콘텐츠를 볼 것인지 여부를 선택할 수 있는 옵션을 사용자에게 명확히 제공해야 합니다. 보상형 광고에는 항상 선택 옵션을 제공해야 합니다.

광고를 표시할 때 사용자의 보상을 처리할 GADUserDidEarnRewardHandler 객체를 제공해야 합니다.

다음 코드는 보상형 광고를 게재하기 위한 최적의 메서드를 나타냅니다.

Swift

func show() {
  guard let rewardedAd = rewardedAd else {
    return print("Ad wasn't ready.")
  }

  // The UIViewController parameter is an optional.
  ad.present(fromRootViewController: nil) {
    let reward = ad.adReward
    print("Reward received with currency \(reward.amount), amount \(reward.amount.doubleValue)")
    // TODO: Reward the user.
  }
}

SwiftUI

뷰에서 UI 이벤트를 수신하여 광고를 표시할 시기를 결정합니다.

var body: some View {
  VStack(spacing: 20) {
      Button("Watch video for additional 10 coins") {
        viewModel.showAd()
        showWatchVideoButton = false
      }

뷰 모델에서 보상형 광고를 표시합니다.

func showAd() {
  guard let rewardedAd = rewardedAd else {
    return print("Ad wasn't ready.")
  }

  rewardedAd.present(fromRootViewController: nil) {
    let reward = rewardedAd.adReward
    print("Reward amount: \(reward.amount)")
    self.addCoins(reward.amount.intValue)
  }
}

Objective-C

- (void)show {
  if (self.rewardedAd) {
    // The UIViewController parameter is nullable.
    [self.rewardedAd presentFromRootViewController:nil
                                  userDidEarnRewardHandler:^{
                                  GADAdReward *reward =
                                      self.rewardedAd.adReward;
                                  // TODO: Reward the user!
                                }];
  } else {
    NSLog(@"Ad wasn't ready");
  }
}

FAQ

GADRewardedAd에 대한 보상 세부정보를 확인할 수 있나요?
예. 가능합니다. userDidEarnReward 콜백이 실행되기 전에 보상 금액을 알아야 하는 경우 GADRewardedAdadReward 속성에서 광고가 로드된 후의 보상 금액을 확인할 수 있습니다.
초기화 호출에 제한 시간이 있나요?
10초가 지나면 미디에이션 네트워크에서 아직 초기화를 완료하지 않은 경우에도 Google 모바일 광고 SDK에서 startWithCompletionHandler: 메서드에 제공된 GADInitializationCompletionHandler를 호출합니다.
초기화 콜백을 받았을 때 일부 미디에이션 네트워크가 준비되지 않은 경우 어떻게 해야 하나요?

GADInitializationCompletionHandler 내에서 광고를 로드하는 것이 좋습니다. 미디에이션 네트워크가 준비되지 않은 경우에도 Google 모바일 광고 SDK에서 해당 네트워크에 광고를 요청합니다. 따라서 미디에이션 네트워크에서 시간이 초과된 후에 초기화를 완료해도 해당 세션에서 향후 광고 요청을 처리할 수 있습니다.

GADMobileAds.initializationStatus를 호출하여 앱 세션 전체에서 모든 어댑터의 초기화 상태를 계속 폴링할 수 있습니다.

특정 미디에이션 네트워크가 준비되지 않은 이유를 확인하려면 어떻게 해야 하나요?

GADAdapterStatus 객체의 description 속성을 보면 어댑터에서 광고 요청을 처리할 준비가 되지 않은 이유를 알 수 있습니다.

userDidEarnRewardHandler 완료 핸들러가 항상 adDidDismissFullScreenContent: 대리자 메서드보다 먼저 호출되나요?

Google 광고의 경우 모든 userDidEarnRewardHandler 호출은 adDidDismissFullScreenContent: 전에 발생합니다. 미디에이션을 통해 게재되는 광고의 경우 서드 파티 광고 네트워크 SDK의 구현에 따라 콜백 순서가 결정됩니다. 단일 대리자 메서드에 리워드 정보를 제공하는 광고 네트워크 SDK의 경우 미디에이션 어댑터가 adDidDismissFullScreenContent: 전에 userDidEarnRewardHandler를 호출합니다.

GitHub의 예

선호하는 언어로 보상형 광고의 전체 예시를 확인하세요.

다음 단계

사용자 개인 정보 보호에 대해 자세히 알아보세요.