شروع به کار

کیت توسعه نرم‌افزار (SDK) پلتفرم پیام‌رسانی کاربر گوگل (UMP) ابزاری برای حفظ حریم خصوصی و پیام‌رسانی است که به شما در مدیریت گزینه‌های حریم خصوصی کمک می‌کند. برای اطلاعات بیشتر، به «درباره حریم خصوصی و پیام‌رسانی» مراجعه کنید.

پیش‌نیازها

  • اندروید API سطح ۲۱ یا بالاتر (برای اندروید)

ایجاد نوع پیام

پیام‌های کاربری را با یکی از انواع پیام‌های کاربری موجود در زیر برگه حریم خصوصی و پیام‌رسانی حساب AdMob خود ایجاد کنید. UMP SDK تلاش می‌کند تا یک پیام حریم خصوصی ایجاد شده از شناسه برنامه AdMob تنظیم شده در پروژه شما را نمایش دهد.

برای جزئیات بیشتر، به «درباره حریم خصوصی و پیام‌رسانی» مراجعه کنید.

SDK را نصب کنید

  1. مراحل نصب Firebase C++ SDK را دنبال کنید. UMP C++ SDK در Firebase C++ SDK گنجانده شده است.

  2. قبل از ادامه، مطمئن شوید که شناسه برنامه AdMob خود را در پروژه پیکربندی کرده‌اید .

  3. در کد خود، UMP SDK را با فراخوانی ConsentInfo::GetInstance() مقداردهی اولیه کنید.

    • در اندروید، باید JNIEnv و Activity ارائه شده توسط NDK را ارسال کنید. این کار را فقط باید در اولین فراخوانی GetInstance() انجام دهید.
    • از طرف دیگر، اگر از قبل از Firebase C++ SDK در برنامه خود استفاده می‌کنید، می‌توانید اولین باری که GetInstance() را فراخوانی می‌کنید، یک firebase::App به آن ارسال کنید.
    #include "firebase/ump/ump.h"
    
    namespace ump = ::firebase::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 SDK را غیرفعال کنید:

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

استفاده از یک Future برای نظارت بر عملیات ناهمزمان

یک firebase::Future راهی برای تعیین وضعیت تکمیل فراخوانی‌های ناهمزمان متد در اختیار شما قرار می‌دهد.

تمام توابع و فراخوانی‌های متد UMP C++ که به صورت غیرهمزمان عمل می‌کنند، یک Future برمی‌گردانند و همچنین یک تابع "آخرین نتیجه" برای بازیابی Future از آخرین عملیات ارائه می‌دهند.

دو راه برای به دست آوردن نتیجه از یک Future وجود دارد:

  1. فراخوانی OnCompletion() و ارسال تابع فراخوانی خودتان که پس از اتمام عملیات فراخوانی می‌شود.
  2. به صورت دوره‌ای status() مربوط به Future را بررسی کنید. وقتی وضعیت از kFutureStatusPending به kFutureStatusCompleted تغییر کرد، عملیات تکمیل شده است.

پس از اتمام عملیات ناهمزمان، باید error() در Future را بررسی کنید تا کد خطای عملیات را بدست آورید. اگر کد خطا 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.
    }
  });
}

به‌روزرسانی حلقه‌ی نظرسنجی

در این مثال، پس از شروع یک عملیات ناهمزمان در هنگام اجرای برنامه، نتایج در جای دیگری، در تابع حلقه به‌روزرسانی بازی (که یک بار در هر فریم اجرا می‌شود) بررسی می‌شوند.

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 مراجعه کنید.

شما باید در هر بار اجرای برنامه، با استفاده از RequestConsentInfoUpdate() درخواست به‌روزرسانی اطلاعات رضایت کاربر را بدهید. این درخواست موارد زیر را بررسی می‌کند:

  • آیا رضایت لازم است ؟ برای مثال، آیا برای اولین بار رضایت لازم است یا تصمیم رضایت قبلی منقضی شده است.
  • اینکه آیا به نقطه ورود گزینه‌های حریم خصوصی نیاز است یا خیر . برخی از پیام‌های حریم خصوصی از برنامه‌ها می‌خواهند که به کاربران اجازه دهند گزینه‌های حریم خصوصی خود را در هر زمانی تغییر دهند.
#include "firebase/ump/ump.h"

namespace ump = ::firebase::ump;

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());
      }
      // Consent information is successfully updated.
    });
}

فرم پیام حریم خصوصی را بارگیری و ارائه دهید

پس از دریافت آخرین وضعیت رضایت، برای بارگذاری هرگونه فرم مورد نیاز برای جمع‌آوری رضایت کاربر، تابع LoadAndShowConsentFormIfRequired() را فراخوانی کنید. پس از بارگذاری، فرم‌ها بلافاصله نمایش داده می‌شوند.

#include "firebase/ump/ump.h"

namespace ump = ::firebase::ump;

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() را مدیریت می‌کند.

گزینه‌های حریم خصوصی

برخی از فرم‌های پیام‌های حریم خصوصی از یک نقطه ورود گزینه‌های حریم خصوصی ارائه شده توسط ناشر ارائه می‌شوند و به کاربران اجازه می‌دهند گزینه‌های حریم خصوصی خود را در هر زمانی مدیریت کنند. برای کسب اطلاعات بیشتر در مورد اینکه کاربران شما در نقطه ورود گزینه‌های حریم خصوصی چه پیامی را می‌بینند، به انواع پیام‌های موجود برای کاربر مراجعه کنید.

درخواست تبلیغات با رضایت کاربر

قبل از درخواست تبلیغات، از ConsentInfo::GetInstance()‑> CanRequestAds() برای بررسی اینکه آیا رضایت کاربر را دریافت کرده‌اید یا خیر، استفاده کنید:

مکان‌های زیر برای بررسی اینکه آیا می‌توانید ضمن جمع‌آوری رضایت، درخواست تبلیغات دهید، فهرست شده‌اند:

  • پس از اینکه UMP SDK در جلسه فعلی رضایت را جمع آوری کرد.
  • بلافاصله پس از اینکه RequestConsentInfoUpdate() را فراخوانی کردید. ممکن است UMP SDK در جلسه قبلی برنامه، رضایت را دریافت کرده باشد.

اگر در طول فرآیند جمع‌آوری رضایت خطایی رخ داد، بررسی کنید که آیا می‌توانید درخواست تبلیغات دهید یا خیر. UMP SDK از وضعیت رضایت جلسه قبلی برنامه استفاده می‌کند.

مثال کامل زیر از نمونه‌برداری حلقه به‌روزرسانی استفاده می‌کند، اما می‌توانید از فراخوانی‌های OnCompletion نیز برای نظارت بر عملیات ناهمزمان استفاده کنید . از هر تکنیکی که با ساختار کد شما سازگارتر است، استفاده کنید.

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

namespace gma = ::firebase::gma;
namespace ump = ::firebase::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. خروجی گزارش را برای پیامی مشابه مثال زیر بررسی کنید، که شناسه دستگاه شما و نحوه اضافه کردن آن به عنوان یک دستگاه آزمایشی را نشان می‌دهد:

    اندروید

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

    آی‌او‌اس

    <UMP SDK>To enable debug mode for this device,
    set: UMPDebugSettings.testDeviceIdentifiers = @[2077ef9a63d2b398840261c8221a0c9b]
    
  3. شناسه دستگاه آزمایشی خود را در کلیپ‌بورد کپی کنید.

  4. کد خود را تغییر دهید تا ConsentRequestParameters.debug_settings.debug_device_ids را روی لیستی از شناسه‌های دستگاه آزمایشی خود تنظیم کنید.

    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 روشی را برای آزمایش رفتار برنامه شما فراهم می‌کند، گویی دستگاه در مناطق مختلفی مانند EEA یا UK قرار دارد، که این کار با استفاده debug_settings.debug_geography انجام می‌شود. توجه داشته باشید که تنظیمات اشکال‌زدایی فقط روی دستگاه‌های آزمایشی کار می‌کنند.

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 برای شبیه‌سازی اولین تجربه نصب کاربر مفید باشد. SDK متد Reset() را برای انجام این کار ارائه می‌دهد.

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