개요
보상형 광고는 사용자가 동영상 광고를 끝까지 시청하면 게임 내 재화, 생명, 힌트 등의 보상을 제공하는 전면 동영상 광고입니다.주요 특징
- 전면 화면을 차지하는 동영상 광고
- 사용자가 광고를 완전히 시청한 경우에만 보상 제공
- 사용자가 직접 광고 시청을 선택 (예: “동영상 보고 생명 받기” 버튼)
- 보상 타입과 수량을 설정 가능
개발 환경에서는 테스트 유닛 ID를 사용하세요:
PUBLIC_TEST_UNIT_ID_REWARDED구현 방법
보상형 광고는 다음과 같은 단계로 구현합니다:- AdropRewardedAd 인스턴스 생성 - 유닛 ID로 광고 객체 생성
- Delegate 설정 - 광고 이벤트 처리를 위한 delegate 지정
- 광고 로드 -
load()메서드로 광고 요청 - 광고 표시 -
show()메서드로 광고 표시 및 보상 처리
Swift 예제
기본 구현
복사
import UIKit
import AdropAds
class RewardedViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
override func viewDidLoad() {
super.viewDidLoad()
// 1. AdropRewardedAd 인스턴스 생성
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
// 2. Delegate 설정
rewardedAd?.delegate = self
// 3. 광고 로드
rewardedAd?.load()
}
@IBAction func showRewardedAdButtonTapped(_ sender: UIButton) {
// 광고가 로드되었는지 확인
guard rewardedAd?.isLoaded == true else {
print("광고가 아직 로드되지 않았습니다")
return
}
// 4. 광고 표시 및 보상 처리
rewardedAd?.show(fromRootViewController: self) { [weak self] type, amount in
// 보상 지급 처리
print("보상 획득 - 타입: \(type), 수량: \(amount)")
self?.grantReward(type: type, amount: amount)
}
}
private func grantReward(type: Int, amount: Int) {
// 사용자에게 보상 지급
// 예: 게임 재화 추가, 생명 회복 등
// ⚠️ 중요: 서버에서 보상을 검증하는 것을 권장합니다
// 클라이언트에서만 보상을 처리하면 부정행위가 가능합니다
}
}
// MARK: - AdropRewardedAdDelegate
extension RewardedViewController: AdropRewardedAdDelegate {
// 필수: 광고 수신 성공
func onAdReceived(_ ad: AdropRewardedAd) {
print("광고 수신 완료")
// 광고 시청 버튼 활성화 등
}
// 필수: 광고 수신 실패
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("광고 수신 실패: \(errorCode)")
// 광고 시청 버튼 비활성화 유지 등
}
// 선택: 광고 노출
func onAdImpression(_ ad: AdropRewardedAd) {
print("광고 노출됨")
}
// 선택: 광고 클릭
func onAdClicked(_ ad: AdropRewardedAd) {
print("광고 클릭됨")
}
// 선택: 광고 화면 표시 직전
func onAdWillPresentFullScreen(_ ad: AdropRewardedAd) {
print("광고 화면 표시 예정")
// 배경 음악 일시정지 등
}
// 선택: 광고 화면 표시 완료
func onAdDidPresentFullScreen(_ ad: AdropRewardedAd) {
print("광고 화면 표시 완료")
}
// 선택: 광고 화면 닫기 직전
func onAdWillDismissFullScreen(_ ad: AdropRewardedAd) {
print("광고 화면 닫기 예정")
}
// 선택: 광고 화면 닫기 완료
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
print("광고 화면 닫힘")
// 배경 음악 재개 등
// 다음 광고 미리 로드
rewardedAd?.load()
}
// 선택: 광고 표시 실패
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("광고 표시 실패: \(errorCode)")
}
}
SwiftUI 예제
복사
import SwiftUI
import AdropAds
class RewardedAdViewModel: NSObject, ObservableObject, AdropRewardedAdDelegate {
@Published var isAdReady = false
@Published var showingAlert = false
@Published var alertMessage = ""
private var rewardedAd: AdropRewardedAd?
override init() {
super.init()
loadAd()
}
func loadAd() {
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
rewardedAd?.delegate = self
rewardedAd?.load()
}
func showAd() {
guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let rootViewController = windowScene.windows.first?.rootViewController else {
return
}
rewardedAd?.show(fromRootViewController: rootViewController) { [weak self] type, amount in
self?.alertMessage = "보상 획득! 타입: \(type), 수량: \(amount)"
self?.showingAlert = true
self?.grantReward(type: type, amount: amount)
}
}
private func grantReward(type: Int, amount: Int) {
// 보상 지급 처리
print("보상 지급 - 타입: \(type), 수량: \(amount)")
}
// MARK: - AdropRewardedAdDelegate
func onAdReceived(_ ad: AdropRewardedAd) {
isAdReady = true
}
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
isAdReady = false
alertMessage = "광고 로드 실패: \(errorCode)"
showingAlert = true
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
isAdReady = false
// 다음 광고 미리 로드
loadAd()
}
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
alertMessage = "광고 표시 실패: \(errorCode)"
showingAlert = true
}
}
struct RewardedAdView: View {
@StateObject private var viewModel = RewardedAdViewModel()
var body: some View {
VStack(spacing: 20) {
Text("보상형 광고 예제")
.font(.title)
Button(action: {
viewModel.showAd()
}) {
Text("동영상 보고 보상 받기")
.padding()
.background(viewModel.isAdReady ? Color.blue : Color.gray)
.foregroundColor(.white)
.cornerRadius(8)
}
.disabled(!viewModel.isAdReady)
}
.alert(isPresented: $viewModel.showingAlert) {
Alert(
title: Text("알림"),
message: Text(viewModel.alertMessage),
dismissButton: .default(Text("확인"))
)
}
}
}
Objective-C 예제
복사
@import AdropAds;
@interface RewardedViewController () <AdropRewardedAdDelegate>
@property (nonatomic, strong) AdropRewardedAd *rewardedAd;
@end
@implementation RewardedViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 1. AdropRewardedAd 인스턴스 생성
self.rewardedAd = [[AdropRewardedAd alloc] initWithUnitId:@"YOUR_UNIT_ID"];
// 2. Delegate 설정
self.rewardedAd.delegate = self;
// 3. 광고 로드
[self.rewardedAd load];
}
- (IBAction)showRewardedAdButtonTapped:(UIButton *)sender {
// 광고가 로드되었는지 확인
if (!self.rewardedAd.isLoaded) {
NSLog(@"광고가 아직 로드되지 않았습니다");
return;
}
// 4. 광고 표시 및 보상 처리
__weak typeof(self) weakSelf = self;
[self.rewardedAd showFromRootViewController:self
userDidEarnRewardHandler:^(NSInteger type, NSInteger amount) {
NSLog(@"보상 획득 - 타입: %ld, 수량: %ld", (long)type, (long)amount);
[weakSelf grantRewardWithType:type amount:amount];
}];
}
- (void)grantRewardWithType:(NSInteger)type amount:(NSInteger)amount {
// 사용자에게 보상 지급
}
#pragma mark - AdropRewardedAdDelegate
// 필수: 광고 수신 성공
- (void)onAdReceived:(AdropRewardedAd *)ad {
NSLog(@"광고 수신 완료");
}
// 필수: 광고 수신 실패
- (void)onAdFailedToReceive:(AdropRewardedAd *)ad :(AdropErrorCode)errorCode {
NSLog(@"광고 수신 실패: %ld", (long)errorCode);
}
// 선택: 광고 노출
- (void)onAdImpression:(AdropRewardedAd *)ad {
NSLog(@"광고 노출됨");
}
// 선택: 광고 클릭
- (void)onAdClicked:(AdropRewardedAd *)ad {
NSLog(@"광고 클릭됨");
}
// 선택: 광고 화면 표시 직전
- (void)onAdWillPresentFullScreen:(AdropRewardedAd *)ad {
NSLog(@"광고 화면 표시 예정");
}
// 선택: 광고 화면 표시 완료
- (void)onAdDidPresentFullScreen:(AdropRewardedAd *)ad {
NSLog(@"광고 화면 표시 완료");
}
// 선택: 광고 화면 닫기 직전
- (void)onAdWillDismissFullScreen:(AdropRewardedAd *)ad {
NSLog(@"광고 화면 닫기 예정");
}
// 선택: 광고 화면 닫기 완료
- (void)onAdDidDismissFullScreen:(AdropRewardedAd *)ad {
NSLog(@"광고 화면 닫힘");
// 다음 광고 미리 로드
[self.rewardedAd load];
}
// 선택: 광고 표시 실패
- (void)onAdFailedToShowFullScreen:(AdropRewardedAd *)ad :(AdropErrorCode)errorCode {
NSLog(@"광고 표시 실패: %ld", (long)errorCode);
}
@end
Delegate 메서드
필수 메서드
광고 수신에 성공했을 때 호출됩니다. 이 시점부터
show() 메서드로 광고를 표시할 수 있습니다.광고 수신에 실패했을 때 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
선택 메서드
광고가 노출되어 노출 기록이 전송되었을 때 호출됩니다.
사용자가 광고를 클릭했을 때 호출됩니다.
광고 화면이 표시되기 직전에 호출됩니다. 배경 음악을 일시정지하는 등의 처리를 할 수 있습니다.
광고 화면이 완전히 표시된 후 호출됩니다.
광고 화면이 닫히기 직전에 호출됩니다.
광고 화면이 완전히 닫힌 후 호출됩니다. 배경 음악을 재개하거나 다음 광고를 미리 로드할 수 있습니다.
광고 표시에 실패했을 때 호출됩니다. 에러 코드를 통해 실패 원인을 확인할 수 있습니다.
보상 처리
보상 콜백
show() 메서드의 userDidEarnRewardHandler 파라미터로 보상 콜백을 전달합니다.
복사
rewardedAd?.show(fromRootViewController: self) { type, amount in
// type: 보상 타입 (Int)
// amount: 보상 수량 (Int)
print("보상 획득 - 타입: \(type), 수량: \(amount)")
}
보상 타입과 수량
- type: 애드컨트롤 콘솔에서 설정한 보상 타입 (정수 값)
- amount: 애드컨트롤 콘솔에서 설정한 보상 수량 (정수 값)
Best Practices
1. 광고 미리 로드하기
사용자 경험을 위해 광고를 미리 로드해두는 것이 좋습니다.복사
class GameViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
override func viewDidLoad() {
super.viewDidLoad()
// 화면 진입 시 광고 미리 로드
loadRewardedAd()
}
private func loadRewardedAd() {
rewardedAd = AdropRewardedAd(unitId: "YOUR_UNIT_ID")
rewardedAd?.delegate = self
rewardedAd?.load()
}
private func showRewardedAd() {
rewardedAd?.show(fromRootViewController: self) { [weak self] type, amount in
self?.grantReward(type: type, amount: amount)
}
}
}
extension GameViewController: AdropRewardedAdDelegate {
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
// 광고가 닫힌 후 다음 광고 미리 로드
loadRewardedAd()
}
}
2. 광고 준비 상태 확인
광고가 로드되었는지 확인하고 UI를 업데이트합니다.복사
class GameViewController: UIViewController {
@IBOutlet weak var watchAdButton: UIButton!
private var rewardedAd: AdropRewardedAd?
private var isAdReady = false
private func updateButtonState() {
watchAdButton.isEnabled = isAdReady
watchAdButton.alpha = isAdReady ? 1.0 : 0.5
watchAdButton.setTitle(
isAdReady ? "동영상 보고 생명 받기" : "광고 로딩중...",
for: .normal
)
}
}
extension GameViewController: AdropRewardedAdDelegate {
func onAdReceived(_ ad: AdropRewardedAd) {
isAdReady = true
updateButtonState()
}
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
isAdReady = false
updateButtonState()
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
isAdReady = false
updateButtonState()
// 다음 광고 로드
rewardedAd?.load()
}
}
3. 배경 음악 처리
광고 표시 전후로 배경 음악을 적절히 제어합니다.복사
extension GameViewController: AdropRewardedAdDelegate {
func onAdWillPresentFullScreen(_ ad: AdropRewardedAd) {
// 광고 표시 직전 배경 음악 일시정지
AudioManager.shared.pauseBackgroundMusic()
}
func onAdDidDismissFullScreen(_ ad: AdropRewardedAd) {
// 광고 종료 후 배경 음악 재개
AudioManager.shared.resumeBackgroundMusic()
}
}
4. 에러 처리
광고 로드 실패 시 재시도 로직을 구현합니다.복사
extension GameViewController: AdropRewardedAdDelegate {
func onAdFailedToReceive(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("광고 로드 실패: \(errorCode)")
// 네트워크 에러인 경우 재시도
if errorCode == .networkError {
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) { [weak self] in
self?.rewardedAd?.load()
}
}
}
func onAdFailedToShowFullScreen(_ ad: AdropRewardedAd, _ errorCode: AdropErrorCode) {
print("광고 표시 실패: \(errorCode)")
// 사용자에게 알림
showAlert(message: "광고를 표시할 수 없습니다. 나중에 다시 시도해주세요.")
}
}
5. 메모리 관리
ViewController가 해제될 때 광고 객체도 정리합니다.복사
class GameViewController: UIViewController {
private var rewardedAd: AdropRewardedAd?
deinit {
rewardedAd?.delegate = nil
rewardedAd = nil
}
}
테스트
테스트 유닛 ID
개발 중에는 항상 테스트 유닛 ID를 사용하세요.복사
// 개발 환경
let rewardedAd = AdropRewardedAd(unitId: "PUBLIC_TEST_UNIT_ID_REWARDED")
// 프로덕션 환경
let rewardedAd = AdropRewardedAd(unitId: "YOUR_PRODUCTION_UNIT_ID")
실제 유닛 ID로 테스트하면 무효 트래픽으로 간주되어 계정이 정지될 수 있습니다. 반드시 테스트 유닛 ID를 사용하세요.
환경별 유닛 ID 관리
빌드 구성에 따라 자동으로 유닛 ID를 변경하는 방법입니다.복사
enum AdUnitID {
static var rewarded: String {
#if DEBUG
return "PUBLIC_TEST_UNIT_ID_REWARDED"
#else
return "YOUR_PRODUCTION_UNIT_ID"
#endif
}
}
// 사용
let rewardedAd = AdropRewardedAd(unitId: AdUnitID.rewarded)