תחילת העבודה

Google User Messaging Platform (UMP) SDK הוא כלי לניהול פרטיות ובקשות הסכמה, שיעזור לכם לנהל את העדפות הפרטיות של המשתמשים. מידע נוסף זמין במאמר מידע על הכלי 'פרטיות והודעות'.

דרישות מוקדמות

  • Android API ברמה 21 ואילך (ל-Android)

יצירת סוג הודעה

אפשר ליצור הודעות למשתמשים באמצעות אחד מהסוגים הזמינים של הודעות למשתמשים בכרטיסייה פרטיות והודעות בחשבון AdMob. UMP SDK מנסה להציג הודעת פרטיות שנוצרה ממזהה האפליקציה ב-AdMob שהוגדר בפרויקט.

פרטים נוספים זמינים במאמר מידע על פרטיות והודעות.

התקנת ה-SDK

  1. פועלים לפי השלבים להתקנת Google Mobile Ads (GMA) C++ SDK. ה-UMP C++ SDK נכלל ב-GMA C++ SDK.

  2. לפני שממשיכים, חשוב להגדיר את מזהה האפליקציה של האפליקציה ב-AdMob בפרויקט.

  3. בקוד, מפעילים את UMP SDK באמצעות קריאה ל-ConsentInfo::GetInstance().

    • ב-Android, צריך להעביר גם את JNIEnv וגם את Activity שמסופקים על ידי NDK. צריך לעשות זאת רק בפעם הראשונה שמתקשרים למספר GetInstance().
    • לחלופין, אם אתם כבר משתמשים ב-Firebase C++ SDK באפליקציה, תוכלו להעביר את הערך firebase::App בפעם הראשונה שתפעילו את האפליקציה GetInstance().
    #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, אתם יכולים להשבית את ה-SDK על ידי מחיקת המכונה ConsentInfo:

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

שימוש ב-Future כדי לעקוב אחרי פעולות אסינכרוניות

באמצעות firebase::Future תוכלו לקבוע את סטטוס השלמת הקריאות לשיטות אסינכרוניות.

כל הפונקציות והקריאות ל-method ב-UMP C++ שפועלות באופן אסינכרוני מחזירות Future, ומספקות גם פונקציית 'last result' לאחזור ה-Future מהפעולה האחרונה.

יש שתי דרכים לקבל תוצאה מ-Future:

  1. קוראים לפונקציה OnCompletion(), ומעבירים את פונקציית הקריאה החוזרת שלכם, שתופעל בסיום הפעולה.
  2. מומלץ לבדוק מדי פעם את status() של Future. כשהסטטוס משתנה מ-kFutureStatusPending ל-kFutureStatusCompleted, הפעולה הושלמה.

אחרי שהפעולה האסינכרונית תושלם, צריך לבדוק את error() של Future כדי לקבל את קוד השגיאה של הפעולה. אם קוד השגיאה הוא 0 (kConsentRequestSuccess או kConsentFormSuccess), הפעולה הושלמה. אחרת, צריך לבדוק את קוד השגיאה ואת error_message() כדי להבין מה השתבש.

התקשרות חזרה בסיום

זוהי דוגמה לשימוש ב-OnCompletion כדי להגדיר קריאה חוזרת (callback) להשלמה, שבה מתבצעת קריאה כשהפעולה האסינכרונית מסתיימת.

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.

כדי לאסוף אישורי הסכמה, מבצעים את השלבים הבאים:

  1. בקשה לקבלת המידע העדכני ביותר בנושא הסכמת המשתמשים.
  2. אם צריך, טוענים טופס הסכמה ומציגים אותו.

צריך לבקש עדכון של פרטי ההסכמה של המשתמש בכל הפעלה של האפליקציה באמצעות RequestConsentInfoUpdate(). הבקשה הזו בודקת את הפרטים הבאים:

  • אם נדרשת הסכמה. לדוגמה, נדרשת הסכמה בפעם הראשונה או שפג התוקף של ההסכמה הקודמת.
  • האם נדרשת נקודת כניסה לאפשרויות הפרטיות. הודעות מסוימות בנושא פרטיות מחייבות שהאפליקציות יאפשרו למשתמשים לשנות את אפשרויות הפרטיות שלהם בכל שלב.

אם צריך, טוענים טופס של הודעת פרטיות ומציגים אותו

אחרי שתקבלו את סטטוס ההסכמה העדכני ביותר, תוכלו להפעיל את הפונקציה LoadAndShowConsentFormIfRequired() כדי לטעון את הטפסים הנדרשים לאיסוף הסכמת המשתמשים. אחרי הטעינה, הטפסים יוצגו באופן מיידי.

הקוד הבא מראה איך לבקש את פרטי ההסכמה העדכניים של המשתמש. אם צריך, הקוד יטען ויציג טופס של הודעת פרטיות:

#include "firebase/gma/ump.h"

namespace ump = ::firebase::gma::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.
          }
        });
      }
    });
}

למעלה מופיעה דוגמה לבדיקת השלמה באמצעות דגימה של לולאת העדכון במקום קריאה חוזרת (callback) להשלמה.

אם אתם צריכים לבצע פעולות כלשהן אחרי שהמשתמש בחר אפשרות או סגר את הטופס, צריך להוסיף את הלוגיקה הזו לקוד שמטפל ב-Future שמוחזר על ידי LoadAndShowConsentFormIfRequired().

אפשרויות פרטיות

חלק מההודעות בנושא פרטיות מוצגות מנקודת כניסה לאפשרויות פרטיות שמוצגת על ידי בעל התוכן הדיגיטלי, ומאפשרות למשתמשים לנהל את אפשרויות הפרטיות שלהם בכל שלב. מידע נוסף על ההודעה שתוצג למשתמשים בנקודת הכניסה לאפשרויות הפרטיות זמין במאמר הסוגים הזמינים של הודעות למשתמשים.

בקשה להצגת מודעות

לפני ששולחים בקשות להצגת מודעות באפליקציה, צריך לבדוק אם קיבלתם מהמשתמש הסכמה באמצעות ConsentInfo::GetInstance()‑> CanRequestAds(). יש שני מקומות שצריך לבדוק בזמן קבלת ההסכמה:

  • אחרי שהתקבלה הסכמה בסשן הנוכחי.
  • מיד אחרי שתתקשרו למספר RequestConsentInfoUpdate(). יכול להיות שהתקבלה הסכמה בסשן הקודם. כדי לצמצם את זמן האחזור, מומלץ לא להמתין להשלמת הקריאה החוזרת כדי שתוכלו להתחיל לטעון מודעות בהקדם האפשרי אחרי השקת האפליקציה.

גם אם מתרחשת שגיאה בתהליך קבלת ההסכמה, עדיין צריך לבדוק אם אפשר לבקש מודעות. ה-SDK של UMP משתמש בסטטוס ההסכמה מהסשן הקודם.

בדוגמה המלאה הבאה נעשה שימוש בסקרים של לולאת עדכון, אבל אפשר גם להשתמש בקריאות חזרה מסוג 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. בודקים בפלט היומן הודעה שדומה לדוגמה הבאה, שבה מוצג מזהה המכשיר ואיך מוסיפים אותו כמכשיר בדיקה:

    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. מעתיקים את מזהה מכשיר הבדיקה ללוח.

  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 SDK אפשר לבדוק את אופן הפעולה של האפליקציה כאילו המכשיר נמצא באזורים שונים, כמו אזור הכלכלי האירופי או בריטניה, באמצעות 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);
}

כשבודקים את האפליקציה באמצעות ה-SDK של UMP, כדאי לאפס את המצב של ה-SDK כדי שתוכלו לדמות את חוויית ההתקנה הראשונה של המשתמש. כדי לעשות זאת, ה-SDK מספק את השיטה Reset().

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