תמיכה בעדכונים בתוך האפליקציה (Unity)

במדריך הזה מוסבר איך להוסיף תמיכה בעדכונים בתוך האפליקציה באפליקציה באמצעות Unity. יש מדריכים נפרדים למקרים שבהם ההטמעה מתבצעת באמצעות שפת התכנות Kotlin או שפת התכנות Java, ולמקרים שבהם ההטמעה מתבצעת באמצעות קוד Native (C/C++).

סקירה כללית של Unity SDK

‫Play in-app update API הוא חלק ממשפחת Play Core SDK. התוסף Unity מציע מחלקה AppUpdateManager לטיפול בתקשורת בין האפליקציה לבין Google Play API. צריך ליצור מופע של המחלקה הזו לפני שמשתמשים בה כדי לנהל עדכונים בתוך האפליקציה:

AppUpdateManager appUpdateManager = new AppUpdateManager();

הגדרת סביבת הפיתוח

OpenUPM-CLI

אם OpenUPM CLI מותקן, אפשר להתקין את מאגר OpenUPM באמצעות הפקודה הבאה:

openupm add com.google.play.appupdate

OpenUPM

  1. פותחים את ההגדרות של מנהל החבילות על ידי בחירה באפשרות בתפריט Unity‏ Edit > Project Settings > Package Manager (עריכה > הגדרות הפרויקט > מנהל החבילות).

  2. מוסיפים את OpenUPM כמאגר חבילות בהיקף מסוים לחלון Package Manager:

    Name: package.openupm.com
    URL: https://package.openupm.com
    Scopes: com.google.external-dependency-manager
      com.google.play.common
      com.google.play.core
      com.google.play.appupdate
    
  3. פותחים את תפריט מנהל החבילות על ידי בחירה באפשרות בתפריט Unity‏ Window > Package Manager (חלון > מנהל החבילות).

  4. בתפריט הנפתח 'היקף חשבון הניהול' בוחרים באפשרות הרישומים שלי.

  5. בוחרים את חבילת Google Play Integrity plugin for Unity מרשימת החבילות ולוחצים על Install (התקנה).

ייבוא מ-GitHub

  1. מורידים את הגרסה האחרונה של .unitypackage מ-GitHub.

  2. מייבאים את הקובץ .unitypackage על ידי בחירה באפשרות התפריט של Unity‏ Assets > Import package > Custom Package (נכסים > ייבוא חבילה > חבילה מותאמת אישית) ומייבאים את כל הפריטים.

בדיקה אם יש עדכונים שצריך להתקין

לפני שמבקשים עדכון, בודקים אם יש עדכון זמין לאפליקציה. אפשר להשתמש ב-AppUpdateManager כדי לבדוק אם יש עדכון בקורוטינה:

IEnumerator CheckForUpdate()
{
  PlayAsyncOperation<AppUpdateInfo, AppUpdateErrorCode> appUpdateInfoOperation =
    appUpdateManager.GetAppUpdateInfo();

  // Wait until the asynchronous operation completes.
  yield return appUpdateInfoOperation;

  if (appUpdateInfoOperation.IsSuccessful)
  {
    var appUpdateInfoResult = appUpdateInfoOperation.GetResult();
    // Check AppUpdateInfo's UpdateAvailability, UpdatePriority,
    // IsUpdateTypeAllowed(), ... and decide whether to ask the user
    // to start an in-app update.
  }
  else
  {
    // Log appUpdateInfoOperation.Error.
  }
}

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

בדיקת עדכונים ישנים

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

כדי לבדוק כמה ימים עברו מאז שהעדכון הפך לזמין דרך חנות Play, אפשר להשתמש ב-ClientVersionStalenessDays:

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

בדיקת העדיפות של העדכון

ממשק ה-API של Google Play למפתחים מאפשר לכם להגדיר את העדיפות של כל עדכון. כך האפליקציה יכולה להחליט עד כמה כדאי להמליץ למשתמש על עדכון. לדוגמה, אפשר להשתמש באסטרטגיה הבאה כדי להגדיר את העדיפות של העדכון:

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

כדי לקבוע את העדיפות, Google Play משתמש בערך של מספר שלם בין 0 ל-5, כאשר 0 הוא ברירת המחדל ו-5 היא העדיפות הגבוהה ביותר. כדי להגדיר את העדיפות של עדכון, משתמשים בשדה inAppUpdatePriority בקטע Edits.tracks.releases בממשק API של Google Play למפתחים. כל הגרסאות החדשות שנוספו לגרסה נחשבות בעדיפות זהה לגרסה. אפשר להגדיר עדיפות רק כשמשיקים גרסה חדשה, ואי אפשר לשנות אותה אחר כך.

מגדירים את העדיפות באמצעות ממשק API של Google Play למפתחים, כפי שמתואר במאמרי העזרה של ה-API של Play Developer. צריך לציין את העדיפות של העדכון בתוך האפליקציה במשאב Edit.tracks שמועבר בשיטה Edit.tracks: update. בדוגמה הבאה מוצגת אפליקציה עם קוד גרסה 88 ו-inAppUpdatePriority 5:

{
  "releases": [{
      "versionCodes": ["88"],
      "inAppUpdatePriority": 5,
      "status": "completed"
  }]
}

בקוד של האפליקציה, אפשר לבדוק את רמת העדיפות של עדכון מסוים באמצעות UpdatePriority:

var priority = appUpdateInfoOperation.UpdatePriority;

התחלת עדכון

אחרי שמוודאים שיש עדכון, אפשר לבקש עדכון באמצעות AppUpdateManager.StartUpdate(). לפני שמבקשים עדכון, חשוב לוודא שיש לכם אובייקט AppUpdateInfo עדכני. צריך גם ליצור אובייקט AppUpdateOptions כדי להגדיר את תהליך העדכון.

בדוגמה הבאה נוצר אובייקט AppUpdateOptions לתהליך עדכון מיידי:

// Creates an AppUpdateOptions defining an immediate in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.ImmediateAppUpdateOptions();

בדוגמה הבאה נוצר אובייקט AppUpdateOptions לתהליך עדכון גמיש:

// Creates an AppUpdateOptions defining a flexible in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.FlexibleAppUpdateOptions();

האובייקט AppUpdateOptions מכיל גם את השדה AllowAssetPackDeletion שקובע אם העדכון יכול למחוק חבילות נכסים במקרה של נפח אחסון מוגבל במכשיר. השדה הזה מוגדר ל-false כברירת מחדל, אבל אפשר להעביר את הארגומנט האופציונלי allowAssetPackDeletion ל-ImmediateAppUpdateOptions() או ל-FlexibleAppUpdateOptions() כדי להגדיר אותו ל-true במקום זאת:

// Creates an AppUpdateOptions for an immediate flow that allows
// asset pack deletion.
var appUpdateOptions =
  AppUpdateOptions.ImmediateAppUpdateOptions(allowAssetPackDeletion: true);

// Creates an AppUpdateOptions for a flexible flow that allows asset
// pack deletion.
var appUpdateOptions =
  AppUpdateOptions.FlexibleAppUpdateOptions(allowAssetPackDeletion: true);

השלבים הבאים תלויים בסוג העדכון שאתם מבקשים: עדכון גמיש או עדכון מיידי.

איך מטפלים בעדכון גמיש

אחרי שיוצרים אובייקט AppUpdateInfo מעודכן ואובייקט AppUpdateOptions עם הגדרה תקינה, אפשר לקרוא ל-AppUpdateManager.StartUpdate() כדי לבקש באופן אסינכרוני תהליך עדכון.

IEnumerator StartFlexibleUpdate()
{
  // Creates an AppUpdateRequest that can be used to monitor the
  // requested in-app update flow.
  var startUpdateRequest = appUpdateManager.StartUpdate(
    // The result returned by PlayAsyncOperation.GetResult().
    appUpdateInfoResult,
    // The AppUpdateOptions created defining the requested in-app update
    // and its parameters.
    appUpdateOptions);

  while (!startUpdateRequest.IsDone)
  {
  // For flexible flow,the user can continue to use the app while
  // the update downloads in the background. You can implement a
  // progress bar showing the download status during this time.
  yield return null;
  }

}

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

IEnumerator CompleteFlexibleUpdate()
{
  var result = appUpdateManager.CompleteUpdate();
  yield return result;

  // If the update completes successfully, then the app restarts and this line
  // is never reached. If this line is reached, then handle the failure (e.g. by
  // logging result.Error or by displaying a message to the user).
}

איך מבצעים עדכון מיידי

אחרי שיוצרים אובייקט AppUpdateInfo מעודכן ואובייקט AppUpdateOptions עם הגדרה תקינה, אפשר לקרוא ל-AppUpdateManager.StartUpdate() כדי לבקש באופן אסינכרוני תהליך עדכון.

IEnumerator StartImmediateUpdate()
{
  // Creates an AppUpdateRequest that can be used to monitor the
  // requested in-app update flow.
  var startUpdateRequest = appUpdateManager.StartUpdate(
    // The result returned by PlayAsyncOperation.GetResult().
    appUpdateInfoResult,
    // The AppUpdateOptions created defining the requested in-app update
    // and its parameters.
    appUpdateOptions);
  yield return startUpdateRequest;

  // If the update completes successfully, then the app restarts and this line
  // is never reached. If this line is reached, then handle the failure (for
  // example, by logging result.Error or by displaying a message to the user).
}

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

טיפול בשגיאות

בקטע הזה מפורטים פתרונות לשגיאות נפוצות.

  • אם הפונקציה StartUpdate() מחזירה ArgumentNullException, זה אומר שהערך של AppUpdateInfo הוא null. לפני שמתחילים את תהליך העדכון, צריך לוודא שאובייקט AppUpdateInfo שמוחזר מ-GetAppUpdateInfo() הוא לא null.
  • אם הפונקציה PlayAsyncOperation מחזירה את קוד השגיאה ErrorUpdateUnavailable, צריך לוודא שיש גרסה מעודכנת של האפליקציה עם אותו מזהה אפליקציה ומפתח חתימה.
  • אם PlayAsyncOperation מחזיר את קוד השגיאה ErrorUpdateNotAllowed, המשמעות היא שאובייקט AppUpdateOptions מציין סוג עדכון שלא מותר לעדכון הזמין. לפני שמתחילים את תהליך העדכון, בודקים אם AppUpdateInfoהאובייקט מציין שסוג העדכון שנבחר מותר.

השלבים הבאים

בודקים את העדכונים בתוך האפליקציה כדי לוודא שהשילוב פועל כמו שצריך.