시작하기

Google 사용자 메시지 플랫폼 (UMP) SDK는 개인 정보 보호 선택사항을 관리하는 데 도움이 됩니다 자세한 내용은 개인정보 보호 및 메시지를 사용하세요.

기본 요건

  • Android API 수준 21 이상 (Android용)

메시지 유형 만들기

다음 중 하나로 사용자 메시지를 작성합니다. 사용 가능한 사용자 메시지 유형 Privacy & 메시지 탭에서 AdMob 있습니다. UMP SDK는 애플리케이션 ID에서 생성된 AdMob 개인 정보 보호 메시지 확인할 수 있습니다

자세한 내용은 개인 정보 보호 및 메시지 정보

SDK 설치

  1. 단계에 따라 Google 모바일 광고 (GMA) C++를 설치합니다. SDK를 사용하는 것이 좋습니다. UMP C++ SDK는 GMA C++ SDK에 포함되어 있습니다.

  2. 앱의 AdMob 앱을 구성해야 합니다. ID 를 선택합니다.

  3. 코드에서 다음을 호출하여 UMP SDK를 초기화합니다. ConsentInfo::GetInstance()

    • Android에서는 개발자가 제공하는 JNIEnvActivity를 전달해야 합니다. NDK를 생성합니다. 이 작업은 GetInstance()를 처음 호출할 때만 실행하면 됩니다.
    • 또는 이미 Firebase C++ SDK를 사용하는 경우 GetInstance()를 처음 호출할 때 firebase::App에서 발생합니다.
    #include "firebase/gma/ump.h"
    
    namespace ump = ::firebase::gma::ump;
    
    // Initialize using a firebase::App
    void InitializeUserMessagingPlatform(const firebase::App& app) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(app);
    }
    
    // Initialize without a firebase::App
    #ifdef ANDROID
    void InitializeUserMessagingPlatform(JNIEnv* jni_env, jobject activity) {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance(jni_env, activity);
    }
    #else  // non-Android
    void InitializeUserMessagingPlatform() {
      ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
    }
    #endif
    

후속 ConsentInfo::GetInstance() 호출은 모두 동일한 인스턴스를 반환합니다.

UMP SDK 사용을 완료한 경우 ConsentInfo 인스턴스:

void ShutdownUserMessagingPlatform() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();
  delete consent_info;
}

Future를 사용하여 비동기 작업 모니터링

firebase::Future 는 비동기 메서드의 완료 상태를 확인하는 방법을 제공합니다. 있습니다.

비동기식으로 작동하는 모든 UMP C++ 함수 및 메서드 호출은 Future 및 '최종 결과'를 제공합니다. Future를 가져오는 함수 가져올 수 있습니다.

Future에서 결과를 가져오는 방법에는 두 가지가 있습니다.

  1. OnCompletion()를 호출합니다. 작업을 호출할 때 호출되는 자체 콜백 함수를 나타냅니다.
  2. Futurestatus()를 주기적으로 확인합니다. 이 상태 kFutureStatusPending에서 kFutureStatusCompleted로 변경되면 작업이 완료되었습니다.

비동기 작업이 완료된 후에는 작업의 오류를 가져오기 위한 Futureerror() 생성합니다. 오류 코드가 0 (kConsentRequestSuccess)인 경우 또는 kConsentFormSuccess) 작업이 성공적으로 완료되었습니다. 오류 코드를 확인하고 error_message()를 사용하여 무엇이 문제인지 확인하세요.

완료 콜백

다음은 OnCompletion를 사용하여 완료 콜백을 설정하는 방법의 예입니다. 이 메서드는 비동기 작업이 완료되면 호출됩니다.

void MyApplicationStart() {
  // [... other app initialization code ...]

  ump::ConsentInfo *consent_info = ump::ConsentInfo::GetInstance();

  // See the section below for more information about RequestConsentInfoUpdate.
  firebase::Future<void> result = consent_info->RequestConsentInfoUpdate(...);

  result.OnCompletion([](const firebase::Future<void>& req_result) {
    if (req_result.error() == ump::kConsentRequestSuccess) {
      // Operation succeeded. You can now call LoadAndShowConsentFormIfRequired().
    } else {
      // Operation failed. Check req_result.error_message() for more information.
    }
  });
}

루프 폴링 업데이트

이 예에서는 앱 시작 시 비동기 작업이 시작된 후 게임의 업데이트 루프 함수 (실행되는 1회).

ump::ConsentInfo *g_consent_info = nullptr;
bool g_waiting_for_request = false;

void MyApplicationStart() {
  // [... other app initialization code ...]

  g_consent_info = ump::ConsentInfo::GetInstance();
  // See the section below for more information about RequestConsentInfoUpdate.
  g_consent_info->RequestConsentInfoUpdate(...);
  g_waiting_for_request = true;
}

// Elsewhere, in the game's update loop, which runs once per frame:
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_waiting_for_request) {
    // Check whether RequestConsentInfoUpdate() has finished.
    // Calling "LastResult" returns the Future for the most recent operation.
    firebase::Future<void> result =
      g_consent_info->RequestConsentInfoUpdateLastResult();

    if (result.status() == firebase::kFutureStatusComplete) {
      g_waiting_for_request = false;
      if (result.error() == ump::kConsentRequestSuccess) {
        // Operation succeeded. You can call LoadAndShowConsentFormIfRequired().
      } else {
        // Operation failed. Check result.error_message() for more information.
      }
    }
  }
}

firebase::Future에 관한 자세한 내용은 Firebase C++ SDK를 참조하세요. 문서GMA C++ SDK 문서를 참고하세요.

애플리케이션 ID 추가

다음에서 애플리케이션 ID를 찾을 수 있습니다. AdMob UI ID를 다음 코드 스니펫으로 대체합니다.

모든 앱에서 사용자 동의 정보 업데이트를 요청해야 합니다. RequestConsentInfoUpdate()를 사용하여 실행합니다. 이 요청은 다음과 같습니다.

  • 동의 필요 여부. 예를 들어 이전 동의 결정이 만료되었습니다.
  • 개인 정보 보호 옵션 진입점의 필요 여부. 일부 개인 정보 보호 메시지 사용자가 언제든지 개인 정보 보호 옵션을 수정하도록 앱에 요구할 수 있습니다.
#include "firebase/gma/ump.h"

namespace ump = ::firebase::gma::ump;

void MyApplicationStart() {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct.
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age
  // of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [](const Future<void>& result) {
      if (result.error() != ump::kConsentRequestSuccess) {
        LogMessage("Error requesting consent update: %s", result.error_message());
      } else {
        // Consent status is now available.
      }
    });
}

다음을 사용하여 완료 여부를 확인하는 예는 를 참조하세요. 업데이트 루프 폴링을 사용해야 합니다.

필요한 경우 개인 정보 보호 메시지 양식 로드 및 표시

최신 동의 상태를 받은 후 LoadAndShowConsentFormIfRequired() 사용자 동의를 수집할 수 있습니다. 로드되면 양식이 즉시 표시됩니다.

void MyApplicationStart(ump::FormParent parent) {
  ump::ConsentInfo* consent_info = ump::ConsentInfo::GetInstance();

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  consent_info->RequestConsentInfoUpdate(params).OnCompletion(
    [*](const Future<void>& req_result) {
      if (req_result.error() != ump::kConsentRequestSuccess) {
        // req_result.error() is a kConsentRequestError enum.
        LogMessage("Error requesting consent update: %s", req_result.error_message());
      } else {
        consent_info->LoadAndShowConsentFormIfRequired(parent).OnCompletion(
        [*](const Future<void>& form_result) {
          if (form_result.error() != ump::kConsentFormSuccess) {
            // form_result.error() is a kConsentFormError enum.
            LogMessage("Error showing privacy message form: %s", form_result.error_message());
          } else {
            // Either the form was shown and completed by the user, or consent was not required.
          }
        });
      }
    });
}

사용자가 결정을 내렸거나 닫은 후 작업을 실행해야 하는 경우 양식에서 Future를 처리하는 코드에 로직을 배치합니다. LoadAndShowConsentFormIfRequired()에서 반환함

공개 설정 옵션

일부 개인 정보 보호 메시지 양식은 게시자가 렌더링한 개인 정보 보호에서 제공됩니다. 옵션 진입점을 사용하여 사용자가 언제든지 개인 정보 보호 옵션을 관리할 수 있습니다. 개인 정보 보호 옵션에서 사용자에게 표시되는 메시지를 자세히 알아보려면 진입점, 사용 가능한 사용자 메시지 유형

개인 정보 보호 옵션 진입점을 구현하려면 다음 단계를 완료하세요.

  1. getPrivacyOptionsRequirementStatus()를 확인합니다.
  2. 개인 정보 보호 옵션 진입점이 필요한 경우 표시 및 상호작용 가능한 UI 요소를 앱에 추가합니다.
  3. 다음 명령어를 사용하여 개인 정보 보호 옵션 양식을 트리거합니다. showPrivacyOptionsForm()

다음 코드 예시는 이러한 단계를 보여줍니다.

광고 요청

앱에서 광고를 요청하기 전에 동의를 얻었는지 확인하세요. ConsentInfo::GetInstance()‑>CanRequestAds()를 사용하여 사용자로부터 반환합니다. 두 가지 동의를 수집할 때 확인해야 할 곳은 다음과 같습니다.

  • 현재 세션에서 동의를 수집한 후
  • RequestConsentInfoUpdate()를 호출한 직후 이전 세션에서 동의를 받았을 수 있습니다. 지연 시간 콜백이 완료될 때까지 기다리지 않는 것이 좋습니다. 그래야 최대한 빨리 광고 로드를 시작하세요
를 호출할 때까지

동의 수집 과정에서 오류가 발생하더라도 광고를 요청할 수 없습니다. UMP SDK는 이전 세션입니다.

다음 전체 예에서는 업데이트 루프 폴링을 사용하지만 OnCompletion 콜백을 사용하여 비동기 작업을 모니터링합니다. 사용 코드 구조에 더 적합한 기법을 사용할 수 있습니다.

#include "firebase/future.h"
#include "firebase/gma/gma.h"
#include "firebase/gma/ump.h"

namespace gma = ::firebase::gma;
namespace ump = ::firebase::gma::ump;
using firebase::Future;

ump::ConsentInfo* g_consent_info = nullptr;
// State variable for tracking the UMP consent flow.
enum { kStart, kRequest, kLoadAndShow, kInitGma, kFinished, kErrorState } g_state = kStart;
bool g_ads_allowed = false;

void MyApplicationStart() {
  g_consent_info = ump::ConsentInfo::GetInstance(...);

  // Create a ConsentRequestParameters struct..
  ump::ConsentRequestParameters params;
  // Set tag for under age of consent. False means users are NOT under age of consent.
  params.tag_for_under_age_of_consent = false;

  g_consent_info->RequestConsentInfoUpdate(params);
  // CanRequestAds() can return a cached value from a previous run immediately.
  g_ads_allowed = g_consent_info->CanRequestAds();
  g_state = kRequest;
}

// This function runs once per frame.
void MyGameUpdateLoop() {
  // [... other game logic here ...]

  if (g_state == kRequest) {
    Future<void> req_result = g_consent_info->RequestConsentInfoUpdateLastResult();

    if (req_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (req_result.error() == ump::kConsentRequestSuccess) {
        // You must provide the FormParent (Android Activity or iOS UIViewController).
        ump::FormParent parent = GetMyFormParent();
        g_consent_info->LoadAndShowConsentFormIfRequired(parent);
        g_state = kLoadAndShow;
      } else {
        LogMessage("Error requesting consent status: %s", req_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kLoadAndShow) {
    Future<void> form_result = g_consent_info->LoadAndShowConsentFormIfRequiredLastResult();

    if (form_result.status() == firebase::kFutureStatusComplete) {
      g_ads_allowed = g_consent_info->CanRequestAds();
      if (form_result.error() == ump::kConsentRequestSuccess) {
        if (g_ads_allowed) {
          // Initialize GMA. This is another asynchronous operation.
          firebase::gma::Initialize();
          g_state = kInitGma;
        } else {
          g_state = kFinished;
        }
        // Optional: shut down the UMP SDK to save memory.
        delete g_consent_info;
        g_consent_info = nullptr;
      } else {
        LogMessage("Error displaying privacy message form: %s", form_result.error_message());
        g_state = kErrorState;
      }
    }
  }
  if (g_state == kInitGma && g_ads_allowed) {
    Future<gma::AdapterInitializationStatus> gma_future = gma::InitializeLastResult();

    if (gma_future.status() == firebase::kFutureStatusComplete) {
      if (gma_future.error() == gma::kAdErrorCodeNone) {
        g_state = kFinished;
        // TODO: Request an ad.
      } else {
        LogMessage("Error initializing GMA: %s", gma_future.error_message());
        g_state = kErrorState;
      }
    }
  }
}

테스트

개발하는 동안 앱에서 통합을 테스트하려면 다음 단계에 따라 테스트 기기를 프로그래매틱 방식으로 등록하세요. 반드시 를 사용하는 것이 좋습니다.

  1. RequestConsentInfoUpdate()를 호출합니다.
  2. 로그 출력에서 다음 예와 비슷한 메시지를 확인합니다. 에 기기 ID와 테스트 기기로 추가하는 방법이 표시됩니다.

    Android

    Use new ConsentDebugSettings.Builder().addTestDeviceHashedId("33BE2250B43518CCDA7DE426D04EE231")
    to set this as a debug device.
    

    iOS

    <UMP SDK>To enable debug mode for this device,
    set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
    
  3. 테스트 기기 ID를 클립보드에 복사합니다.

  4. 코드를 수정하여 ConsentRequestParameters.debug_settings.debug_device_ids 받는사람 테스트 기기 ID 목록입니다.

    void MyApplicationStart() {
      ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);
    
      ump::ConsentRequestParameters params;
      params.tag_for_under_age_of_consent = false;
      params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
    
      consent_info->RequestConsentInfoUpdate(params);
    }
    

지역 강제 설정

UMP SDK는 마치 기기가 제대로 작동하지 않는 것처럼 앱 동작을 테스트하는 방법을 제공합니다. ConsentRequestParameters.debug_settings.debug_geography를 사용하여 EEA 또는 영국에 거주 참고: 디버그 설정은 테스트 기기에서만 작동합니다.

void MyApplicationStart() {
  ump::ConsentInfo consent_info = ump::ConsentInfo::GetInstance(...);

  ump::ConsentRequestParameters params;
  params.tag_for_under_age_of_consent = false;
  params.debug_settings.debug_device_ids = {"TEST-DEVICE-HASHED-ID"};
  // Geography appears as EEA for debug devices.
  params.debug_settings.debug_geography = ump::kConsentDebugGeographyEEA

  consent_info->RequestConsentInfoUpdate(params);
}

UMP SDK로 앱을 테스트할 때 사용자의 첫 설치 환경을 시뮬레이션할 수 있습니다. SDK에서는 이를 위한 Reset() 메서드를 제공합니다.

  ConsentInfo::GetInstance()->Reset();

GitHub의 예