오퍼월

오퍼월은 사용자가 광고를 보고 참여해서 포인트를 받을 수 있는 화면입니다. 애드체인 오퍼월은 단순한 광고 목록이 아닌, 퀴즈 콘텐츠와 AI 추천을 활용한 사용자 참여형 오퍼월 솔루션입니다.

기본 사용법

전체 화면 오퍼월

가장 일반적인 방법입니다. 버튼을 누르면 오퍼월이 전체 화면으로 뜹니다.

Android:

AdchainSdk.openOfferwall(
    activity = this,
    placementId = "main_button",  // 어디서 열렸는지 구분용
    listener = object : AdchainOfferwallListener {
        override fun onOpen() {
            // 오퍼월이 열렸을 때
        }

        override fun onClose() {
            // 오퍼월이 닫혔을 때
            // 여기서 사용자 포인트를 다시 가져오면 됩니다
        }

        override fun onError(error: AdchainError) {
            // 에러가 났을 때
            Toast.makeText(this@MainActivity, "오류: ${error.message}", Toast.LENGTH_SHORT).show()
        }
    }
)

iOS:

AdchainSdk.shared.openOfferwall(
    viewController: self,
    placementId: "main_button",
    listener: OfferwallListener()
)

class OfferwallListener: AdchainOfferwallDelegate {
    func onOpen() {
        print("오퍼월 열림")
    }

    func onClose() {
        print("오퍼월 닫힘")
        // 여기서 포인트 갱신하면 좋습니다
    }

    func onError(error: AdchainError) {
        print("오류: \(error.message)")
    }
}

React Native:

import { AdchainSdk } from '@1selfworld/adchain-sdk-react-native';

const openOfferwall = async () => {
  try {
    await AdchainSdk.openOfferwall('main_button');
  } catch (error) {
    console.error('오퍼월 열기 실패:', error);
  }
};

placementId는 뭔가요?

오퍼월을 다양한 위치에서 열 수 있습니다. 메인 화면 버튼, 설정 화면, 프로필 화면 등이 있습니다. placementId는 어느 위치에서 오퍼월이 열렸는지 구분하기 위해 사용됩니다.

placementId를 활용하여 데이터 분석과 어느 지면에서 사용자들의 오퍼월 활용이 많았는지 확인할 수 있습니다. placementId는 사용하는 API에 따라 해석 방법이 달라질 수 있으므로, 애드체인 개발팀과 사전 협의하는 것이 좋습니다:

  • "main_button" - 메인 화면 버튼

  • "profile_menu" - 프로필 메뉴

  • "daily_mission" - 데일리 미션에서

  • "tab_benefits" - 혜택 탭에서

임베디드 오퍼월 (화면 일부에 넣기)

전체 화면이 아니라 앱 화면의 일부(예: 탭이나 섹션)에 오퍼월을 계속 띄워두고 싶을 수 있습니다.

Android

XML 레이아웃에:

<com.adchain.sdk.offerwall.AdchainOfferwallView
    android:id="@+id/offerwallView"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

Activity나 Fragment에서:

val offerwallView = findViewById<AdchainOfferwallView>(R.id.offerwallView)

// 오퍼월 로드
offerwallView.load(placementId = "benefits_tab")

// 리스너는 선택사항
offerwallView.setListener(object : AdchainOfferwallListener {
    override fun onOpen() {}
    override fun onClose() {}
    override fun onError(error: AdchainError) {}
})

// Fragment가 파괴될 때 cleanup
override fun onDestroyView() {
    super.onDestroyView()
    offerwallView.destroy()
}

iOS

UIKit:

import AdChainSDK

class BenefitsViewController: UIViewController {
    private var offerwallView: AdchainOfferwallView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // 오퍼월 뷰 생성
        offerwallView = AdchainOfferwallView(frame: view.bounds)
        offerwallView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        view.addSubview(offerwallView)

        // 로드
        offerwallView.load(placementId: "benefits_tab")
    }

    deinit {
        offerwallView?.cleanup()
    }
}

SwiftUI는 UIViewRepresentable로 감싸면 됩니다:

struct OfferwallViewWrapper: UIViewRepresentable {
    let placementId: String

    func makeUIView(context: Context) -> AdchainOfferwallView {
        let view = AdchainOfferwallView()
        view.load(placementId: placementId)
        return view
    }

    func updateUIView(_ uiView: AdchainOfferwallView, context: Context) {
        // 필요하면 업데이트
    }
}

// 사용
struct BenefitsView: View {
    var body: some View {
        OfferwallViewWrapper(placementId: "benefits_tab")
            .edgesIgnoringSafeArea(.all)
    }
}

React Native

import React from 'react';
import { StyleSheet, View } from 'react-native';
import { AdchainOfferwallView } from '@1selfworld/adchain-sdk-react-native';

function BenefitsScreen() {
  return (
    <View style={styles.container}>
      <AdchainOfferwallView
        style={styles.offerwall}
        placementId="benefits_tab"
        onLoad={() => console.log('로드됨')}
        onError={(error) => console.error('에러:', error)}
      />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  offerwall: {
    flex: 1,
  },
});

커스텀 URL로 오퍼월 열기

특수한 경우에, 애드체인 서버에서 받은 URL로 오퍼월을 열어야 할 수도 있습니다:

Android:

AdchainSdk.openOfferwallWithUrl(
    activity = this,
    url = "https://hub.adchain.com/custom/path",
    placementId = "custom"
)

iOS:

AdchainSdk.shared.openOfferwallWithUrl(
    viewController: self,
    url: "https://hub.adchain.com/custom/path",
    placementId: "custom"
)

React Native:

await AdchainSdk.openOfferwallWithUrl(
  'https://hub.adchain.com/custom/path',
  'custom'
);

일반적으로는 사용하지 않습니다. 특별한 프로모션 페이지를 열어야 하는 경우 사용할 수 있습니다.

Adjoe 오퍼월 통합

SDK는 Adjoe(구 PlaytimeWeb)와도 연동됩니다. Adjoe는 게임 플레이타임 기반 보상 광고 서비스로, 게임 앱에 최적화되어 있습니다.

Android:

AdchainSdk.openAdjoeOfferwall(
    activity = this,
    placementId = "adjoe_section"
)

iOS:

AdchainSdk.shared.openAdjoeOfferwall(
    viewController: self,
    placementId: "adjoe_section"
)

React Native:

await AdchainSdk.openAdjoeOfferwall('adjoe_section');

Adjoe 광고는 SDK가 자동으로 처리하기 때문에 따로 Adjoe SDK를 설치할 필요 없습니다.

오퍼월이 안 열리는 경우

오퍼월이 안 열린다면 다음을 확인해보세요:

  1. SDK 초기화 확인

    // Android
    if (!AdchainSdk.isInitialized()) {
        // 초기화 안 됨
    }
    
    // iOS
    if !AdchainSdk.shared.isInitialized {
        // 초기화 안 됨
    }
  2. 로그인 확인

    // Android
    if (!AdchainSdk.isLoggedIn) {
        // 로그인 안 됨
    }
    
    // iOS
    if !AdchainSdk.shared.isLoggedIn {
        // 로그인 안 됨
    }
  3. 인터넷 연결 확인

    오퍼월은 WebView로 작동하기 때문에 인터넷이 필요합니다.

  4. 로그 확인

    Android: Logcat에서 AdChain 태그로 필터링 iOS: Console.app에서 AdChain 검색

오퍼월이 느릴 때

오퍼월 첫 로딩이 느리다면:

  • 첫 로딩은 WebView 초기화 + 콘텐츠 로드 때문에 2-3초 걸릴 수 있습니다

  • 두 번째부터는 캐시가 있어서 빠릅니다

  • 사용자 네트워크 상태에 따라 다를 수 있습니다

미리 로딩해두려면:

Android:

// 앱 시작할 때 미리 초기화
val offerwallView = AdchainOfferwallView(context)
offerwallView.load(placementId = "preload")
// 나중에 destroy() 꼭 호출

iOS:

// 앱 시작할 때 미리 초기화
let offerwallView = AdchainOfferwallView()
offerwallView.load(placementId: "preload")
// 나중에 cleanup() 꼭 호출

다음 단계

Last updated