visual_reward 1.2.0 copy "visual_reward: ^1.2.0" to clipboard
visual_reward: ^1.2.0 copied to clipboard

Tenqube Visual Reward SDK for Flutter. A reward-ad webview SDK built on flutter_inappwebview for Android and iOS.

Flutter #

Flutter InAppWebView 기반 리워드 광고 SDK입니다.

요구사항 #

  • Flutter 3.38.1+
  • Dart 3.10.0+
  • iOS 14.0+
  • Android minSdk 24

설치 #

pub.dev #

dependencies:
  # visual_reward SDK
  visual_reward: ^1.2.0

  # ⚠️ google_mobile_ads 는 사용하지 마세요. GMA 는 플랫폼별로 직접 링크합니다.
  #    아래 「GMA SDK」 절을 참고하세요.

  # Native Ads SDK 어댑터 (Rewarded/Interstitial). 코어와 같은 버전을 사용합니다.
  visual_reward_ezoic: ^1.2.0

  # Native Ads SDK 초기화용 공식 패키지 (git 으로만 배포됩니다).
  ezoic_flutter_sdk:
    git:
      url: https://github.com/ezoic/flutter-sdk.git
      ref: v1.5.0 # 반드시 고정하세요 (아래 참고)

ref 를 생략하면 flutter pub get 시점의 최신 커밋을 받아 Native Ads SDK 버전이 앱마다 달라집니다. 어댑터는 1.5.0 에 맞춰 컴파일돼 있으므로 ref: v1.5.0 을 사용하고, 상위 버전이 필요하면 요청해주세요.

  • GMA SDK 는 플랫폼별로 직접 링크합니다. 아래 「GMA SDK」 절을 참고하세요.

  • iOS Podfile 에 정적 링크를 지정합니다. Native Ads SDK 가 의존하는 Google Mobile Ads / UMP가 정적 라이브러리라, 없으면 pod install이 transitive dependencies that include statically linked binaries 오류로 실패합니다.

    # ios/Podfile
    platform :ios, '14.0'
    
    target 'Runner' do
      use_frameworks! :linkage => :static   # 기존 use_frameworks! 를 이 줄로 교체
      use_modular_headers!
      flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
    end
    

GMA SDK #

  • GMA 는 웹뷰 내부 광고(AdSense/GPT/IMA HTML5)의 수익화·측정 신호용입니다. 링크돼 있으면 SDK가 리워드 웹뷰를 registerWebView 에 자동 등록합니다.

  • google_mobile_ads 플러그인은 사용할 수 없습니다. Native Ads SDK 를 함께 쓸 때 Android·iOS 양쪽 제약을 동시에 만족하는 버전이 없습니다.

    google_mobile_ads Android play-services-ads iOS Google-Mobile-Ads-SDK
    ~ 5.3.1 23.6.0 ✅ ~ 11.13 ❌
    6.0.0 ~ 24.1.0 ~ ❌ 12.2 ~ ✅
    • Android: GMA 24.0.0 에서 AdManagerAdRequest.Builder.addCustomTargeting(String, String) 의 covariant 오버라이드가 제거돼, 이를 호출하는 Native Ads SDK 1.5.0 이 광고 로드 시 NoSuchMethodError 로 크래시합니다. → 23.6.0 이하 필요
    • iOS: Native Ads SDK 가 Google-Mobile-Ads-SDK ~> 12.0 을 요구해 11.x 로는 pod install 이 실패합니다. → 12.x 필요
  • 따라서 플랫폼별로 직접 링크합니다.

    // android/app/build.gradle.kts
    dependencies {
        // ⚠️ 24.x 이상으로 올리지 마세요 (위 사유)
        implementation("com.google.android.gms:play-services-ads:23.6.0")
    }
    

    iOS 는 Native Ads SDK 가 GMA 12.x 를 가져오므로 추가 선언이 필요 없습니다.

  • Native Ads SDK(visual_reward_ezoic)를 쓰지 않는다면 위 Android 제약은 적용되지 않습니다.

App ID #

  • 호스트 앱에 AdMob/Ad Manager App ID가 필요합니다. ID가 없는 경우 요청주시기 바랍니다.
  • App ID가 누락되면 앱 시작 시 크래시가 발생합니다.
  1. AndroidManifest.xml

    <application>
        <meta-data
            android:name="com.google.android.gms.ads.APPLICATION_ID"
            android:value="ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" />
        <!-- 웹뷰 내부 광고만 서빙할 때 추가. 자체 광고(Rewarded/Interstitial)도 서빙하면 이 메타데이터는 넣지 않습니다 -->
        <meta-data
            android:name="com.google.android.gms.ads.INTEGRATION_MANAGER"
            android:value="webview" />
    </application>
    
  2. Info.plist

    <key>GADApplicationIdentifier</key>
    <string>ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy</string>
    <!-- 웹뷰 내부 광고만 서빙할 때 추가. 자체 광고(Rewarded/Interstitial)도 서빙하면 이 키는 넣지 않습니다 -->
    <key>GADIntegrationManager</key>
    <string>webview</string>
    
    <!-- IDFA/ATT 사용 목적 문자열 -->
    <key>NSUserTrackingUsageDescription</key>
    <string>맞춤형 광고 제공을 위해 기기 식별자를 사용합니다.</string>
    
    <!-- SKAdNetwork (Google 제공 식별자) -->
    <key>SKAdNetworkItems</key>
    <array><!-- ... --></array>
    

    ATT 권한 요청은 SDK가 웹뷰 로드 전 네이티브 ATTrackingManager로 자동 처리합니다. 이미 권한이 결정된 경우 팝업 없이 즉시 진행하며, NSUserTrackingUsageDescription이 없으면 요청을 스킵하고 바로 로드합니다.

app-ads.txt #

  • 앱 스토어 등록정보의 개발자 웹사이트 도메인 루트 app-ads.txt에 전달받은 목록을 그대로 복사하여 게시해주세요.

시퀀스 다이어그램 #

sequenceDiagram
    title interaction VisualReward SDK

    participant A as Host App
    participant B as VisualReward SDK
    participant C as VisualReward 서버
    participant D as WebView 화면

    A->>B: initialize(appKey, ...)
    B->>C: config 요청
    C-->>B: config 응답
    B-->>A: onSuccess()

    A->>B: setUserId(userId)

    A->>B: open(serviceName, ...)
    B->>D: 웹뷰 열기

    D->>B: 웹뷰 닫힘
    B-->>A: onClose

사용법 #

디버그 설정 #

  • initialize() 전에 호출합니다.

    import 'package:visual_reward/visual_reward.dart';
    
    VisualReward.setDebugEnabled(kDebugMode);
    

초기화 #

  • main() 또는 앱 시작 시 한 번만 호출합니다.

  • 어댑터 등록 코드는 없습니다 — visual_reward_ezoic 을 의존성에 추가하면 SDK가 자동으로 인식합니다.

    import 'package:ezoic_flutter_sdk/ezoic_flutter_sdk.dart';
    import 'package:flutter/widgets.dart';
    import 'package:visual_reward/visual_reward.dart';
    // visual_reward_ezoic 은 import 하지 않습니다 — 의존성에 추가하기만 하면 자동 등록됩니다.
    
    // 준비 상태 플래그 (예: 앱 전역에서 보관)
    var adsReady = false;
    var rewardReady = false;
    
    Future<void> main() async {
      WidgetsFlutterBinding.ensureInitialized();
    
      // GMA 는 명시적 초기화가 필요 없습니다.
      //  - Android: MobileAdsInitProvider 가 앱 시작 시 자동 초기화합니다
      //             (App ID 는 AndroidManifest 메타데이터로 지정)
      //  - 양 플랫폼 모두 Native Ads SDK 가 initialize 중 GMA 를 초기화합니다
    
      // 1) Native Ads SDK 초기화
      // ⚠️ 이 SDK는 초기화 중 ATT 프롬프트를 기본으로 표시합니다(requestATTBeforeAds 기본 true).
      //    앱이 자체 ATT 플로우로 시점을 통제하려면 requestATTBeforeAds: false 를 주세요.
      try {
        await EzoicAds.initialize(const EzoicConfiguration(
          domain: 'example.com', // 발급된 domain
          debugEnabled: false,
          testMode: false,
        ));
        adsReady = true;
      } catch (_) { /* Native Ads SDK 초기화 실패 */ }
    
      // 2) VisualReward SDK 초기화
      VisualReward.initialize(
        appKey: 'tq_live_xxx',                // 발급된 app_key
        timeout: const Duration(seconds: 5),  // 기본값
        onSuccess: () => rewardReady = true,
        onFailure: (e) { /* 초기화 실패 */ },
      );
    
      runApp(const MyApp());
    }
    
  • VisualReward.initialize 파라미터

    파라미터 타입 필수 설명 기본값
    appKey String ✅ stage별 app_key 발급 요청이 필요합니다.
    timeout Duration 초기화 완료 대기 시간. 초과 시 VisualRewardInitializeTimeoutError 발생 Duration(seconds: 5)
    onSuccess VoidCallback? 초기화 성공 콜백 null
    onFailure void Function(VisualRewardError)? 초기화 실패 콜백 null
  • EzoicConfiguration 파라미터

    파라미터 타입 필수 설명 기본값
    domain String ✅ 도메인 값 발급 요청 필요합니다.
    autoReadConsent bool 설치된 CMP의 동의 값 자동 사용 true
    subjectToCOPPA bool COPPA 대상 여부 false
    requestATTBeforeAds bool 초기화 중 ATT 프롬프트 자동 표시 (iOS 전용) true
    debugEnabled bool 네이티브 광고 디버그 활성화 false
    testMode bool 테스트 광고 노출 여부. 실제 광고가 아닌 테스트용 광고 사용됩니다. false

    iOS ATT 프롬프트가 두 곳에서 요청됩니다. Native Ads SDK는 initialize 중(requestATTBeforeAds 기본 true), Visual Reward SDK는 웹뷰 로드 직전에 각각 요청합니다. 먼저 실행된 쪽이 팝업을 띄우고 나머지는 이미 결정된 상태를 보고 통과하므로 팝업이 두 번 뜨지는 않습니다.

    Rewarded / Interstitial 광고는 웹 페이지가 요청합니다. 호스트가 광고를 직접 로드·표시하는 코드는 필요하지 않습니다.

사용자 설정 #

  • 로그인 후 또는 사용자가 변경될 때 호출합니다. open() 전에 반드시 호출해야 합니다.

    VisualReward.setUserId(user.id);
    

웹뷰 열기 #

  • initialize() 후에 호출합니다.

    import 'package:visual_reward/visual_reward.dart';
    
    VisualReward.open(
      context: context,
      serviceName: 'reward_home',
      locale: 'ko',
      extra: null,
      onClose: () { /* 웹뷰 닫힘 */ },
      onError: (e) { /* 열기 실패 */ },
    );
    
  • open 파라미터

    파라미터 타입 필수 설명 기본값
    context BuildContext ✅ 화면을 열 BuildContext
    serviceName String ✅ 사용 서비스별 serviceName 전달 예정입니다.
    locale String? BCP 47 (RFC 5646) 언어 서브태그(ISO 639-1, 2자리 소문자)를 사용 "ko"
    extra String? 포스트백 추가 데이터 (JSON serialize된 문자열) null
    onClose VoidCallback? 웹뷰가 닫힐 때 호출되는 콜백 null
    onError void Function(VisualRewardError)? 에러 발생 시 호출되는 콜백 null

AdPopcorn 브릿지 등록 #

  • AdPopcorn SDK(adpopcornssp_flutter)를 사용하는 경우 open 호출 전에 등록합니다.

    import 'package:adpopcornssp_flutter/adpopcornssp_flutter.dart';
    
    VisualReward.setAdPopcornBridgeHandler(AdPopcornInAppWebViewBridgeHandler());
    

에러 처리 #

에러 타입 #

타입 설명
VisualRewardNetworkError 네트워크 연결 실패
VisualRewardInitializeTimeoutError initialize() 호출 후 완료까지 타임아웃
VisualRewardInvalidAppKeyError 유효하지 않은 앱 키 (404)
VisualRewardServerError(statusCode) 서버 오류 (5xx)
VisualRewardParseError 응답 파싱 실패
VisualRewardNotInitializedError initialize() 호출 없이 open() 호출
VisualRewardUserIdNotSetError setUserId() 호출 없이 open() 호출

initialize 에러 처리 #

  • onFailure 콜백에서 에러 타입을 분기합니다.

    VisualReward.initialize(
      appKey: 'tq_live_xxx',
      timeout: const Duration(seconds: 5),
      onSuccess: () { /* SDK 준비 완료 */ },
      onFailure: (e) {
        if (e is VisualRewardNetworkError) {
          // 네트워크 연결 실패
        } else if (e is VisualRewardInitializeTimeoutError) {
          // 초기화 타임아웃
        } else if (e is VisualRewardInvalidAppKeyError) {
          // 존재하지 않는 앱 키
        } else if (e is VisualRewardServerError) {
          // 서버 오류: e.statusCode
        } else if (e is VisualRewardParseError) {
          // 응답 파싱 실패
        }
      },
    );
    

open 에러 처리 #

  • open()은 예외를 throw하지 않고 onError 콜백으로 에러를 전달합니다. 콜백에서 에러 타입을 분기합니다.

    VisualReward.open(
      context: context,
      serviceName: 'reward_home',
      locale: 'ko',
      extra: null,
      onError: (e) {
        if (e is VisualRewardNotInitializedError) {
          // initialize() 미호출
        } else if (e is VisualRewardUserIdNotSetError) {
          // setUserId() 미호출
        } else if (e is VisualRewardNetworkError) {
          // 네트워크 연결 실패
        } else if (e is VisualRewardServerError) {
          // 서버 오류: e.statusCode
        }
      },
    );
    
0
likes
0
points
460
downloads

Publisher

verified publishertenqube.com

Weekly Downloads

Tenqube Visual Reward SDK for Flutter. A reward-ad webview SDK built on flutter_inappwebview for Android and iOS.

Homepage
Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, flutter_inappwebview

More

Packages that depend on visual_reward

Packages that implement visual_reward