دعم التحديثات داخل التطبيق (Unity)

يوضّح هذا الدليل كيفية إتاحة التحديثات داخل التطبيق في تطبيقك باستخدام Unity. تتوفّر أدلّة مفصّلة للحالات التي يستخدم فيها التنفيذ لغة برمجة Kotlin أو لغة برمجة Java، والحالات التي يستخدم فيها التنفيذ رمزًا أصليًا (C/C++).

إعداد بيئة التطوير

OpenUPM-CLI

إذا كان لديك واجهة برمجة التطبيقات OpenUPM مثبّتة، يمكنك تثبيت قاعدة بيانات المسجّلين OpenUPM باستخدام الأمر التالي:

openupm add com.google.play.appupdate

OpenUPM

  1. افتح إعدادات مدير الحِزم من خلال اختيار خيار قائمة Unity تعديل > إعدادات المشروع > مدير الحِزم.

  2. أضِف OpenUPM كسجلّ نطاقي إلى نافذة "مدير الحِزم":

    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 نافذة > مدير الحِزم.

  4. اضبط القائمة المنسدلة لنطاق المدير لاختيار سجلّاتي.

  5. اختَر حزمة Google Play Integrity plugin for Unity من قائمة الحِزم واضغط على تثبيت.

الاستيراد من GitHub

  1. نزِّل أحدث إصدار من .unitypackage من GitHub.

  2. استورِد ملف .unitypackage من خلال اختيار خيار قائمة Unity التالي: مواد العرض > استيراد حزمة > حزمة مخصّصة واستيراد جميع العناصر.

نظرة عامة على حزمة تطوير البرامج (SDK) في Unity

تشكّل واجهة برمجة التطبيقات "تحديث التطبيق من داخله" في Play جزءًا من عائلة حزمة تطوير البرامج (SDK) Play Core. يوفّر "مكوّن Unity Plugin" فئة AppUpdateManager لمعالجة الاتصالات بين تطبيقك وواجهة برمجة التطبيقات Play API. يجب إنشاء مثيل لهذه الفئة قبل استخدامها لإدارة التحديثات داخل التطبيق:

AppUpdateManager appUpdateManager = new AppUpdateManager();

التحقّق من توفّر تحديث

قبل طلب تحديث، تحقّق مما إذا كان هناك تحديث متوفّر لتطبيقك. استخدِم 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(), etc. and decide whether to ask the user
    // to start an in-app update.
  }
  else
  {
    // Log appUpdateInfoOperation.Error.
  }
}

يحتوي العنصر المعروض AppUpdateInfo الذي تم إرجاعه على حالة توفّر التحديث. إذا كان التحديث داخل التطبيق قيد التقدّم، تُبلغ النسخة أيضًا عن حالة التحديث الجاري.

التحقّق من تقادم التحديث

بالإضافة إلى التحقّق مما إذا كان تحديث متاحًا، ننصحك أيضًا بمحاولة معرفة المدّة التي انقضت منذ إرسال آخر إشعار للمستخدم بشأن تحديث من خلال "متجر Play". يمكن أن يساعدك ذلك في تحديد ما إذا كان عليك بدء تعديل مرن أو تعديل فوري. على سبيل المثال، يمكنك الانتظار لبضعة أيام قبل إرسال إشعار للمستخدم بإجراء تعديل مرن، ثم الانتظار لبضعة أيام بعد ذلك قبل طلب إجراء تعديل فوري.

استخدِم ClientVersionStalenessDays للتحقّق من عدد الأيام التي مرّت منذ توفّر التحديث من خلال "متجر Play":

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

التحقّق من أولوية التحديث

تتيح لك واجهة برمجة التطبيقات Google Play Developer API ضبط أولوية كل تحديث. يتيح ذلك لتطبيقك تحديد مدى قوة اقتراح التحديث على المستخدم. على سبيل المثال، إليك الاستراتيجية التالية لتحديد أولوية التحديث:

  • تحسينات طفيفة في واجهة المستخدم: تحديث ذو أولوية منخفضة، لا يتطلّب تحديثًا مرنًا ولا تحديثًا فوريًا.
  • تحسينات الأداء: تحديث ذو أولوية متوسطة، يُرجى طلب تعديلٍ مرن.
  • تحديث أمان مهم: تحديث ذو أولوية عالية، يُرجى طلب التحديث فورًا.

لتحديد الأولوية، يستخدم Google Play قيمة عددية بين 0 و5، وتكون القيمة 0 هي القيمة التلقائية و5 هي أعلى قيمة. لتحديد الأولوية لأحد التحديثات، استخدِم الحقل inAppUpdatePriority ضمن Edits.tracks.releases في Google Play Developer API. وجميع الإصدارات المُضافة حديثًا في الإصدار تُعتبر ذات الأولوية نفسها التي يحظى بها الإصدار. لا يمكن ضبط الأولوية إلا عند طرح إصدار جديد، ولا يمكن تغييرها لاحقًا.

اضبط الأولوية باستخدام Google Play Developer API كما هو موضّح في مستندات Play Developer API. يجب تحديد أولوية التحديث داخل التطبيق في ملف موارد 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);

تعتمد الخطوات التالية على ما إذا كنت تطلب تعديلًا FLEXIBLE أو تعديلًا فوريًا.

التعامل مع تعديل مرن

بعد الحصول على عنصر 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 فارغة. تأكَّد من أنّ عنصر AppUpdateInfo الذي تم إرجاعه من GetAppUpdateInfo() ليس فارغًا قبل بدء عملية التعديل.
  • إذا عرضت PlayAsyncOperation رمز الخطأ ErrorUpdateUnavailable، تأكَّد من توفّر إصدار معدَّل من التطبيق يتضمّن رقم تعريف التطبيق نفسه ومفتاح التوقيع نفسه.
  • إذا عرض العنصر PlayAsyncOperation رمز الخطأ ErrorUpdateNotAllowed، يعني ذلك أنّ العنصر AppUpdateOptions يشير إلى نوع تحديث غير مسموح به للتحديث المتاح. تحقَّق مما إذا كان عنصر AppUpdateInfo يشير إلى أنّ نوع التعديل المحدّد مسموح به قبل بدء عملية تعديل.

الخطوات التالية

اختبِر التعديلات داخل التطبيق للتأكّد من أنّ عملية الدمج تعمل بشكلٍ صحيح.