يوضّح هذا الدليل كيفية إتاحة التحديثات داخل التطبيق في تطبيقك باستخدام Unity. تتوفّر أدلة منفصلة للحالات التي يستخدم فيها التنفيذ لغة برمجة Kotlin أو لغة برمجة Java، والحالات التي يستخدم فيها التنفيذ رمزًا أصليًا (C/C++).
نظرة عامة على حزمة تطوير البرامج (SDK) في Unity
تشكّل واجهة برمجة التطبيقات Play in-app update API جزءًا من مجموعة Play Core SDK. يوفّر "مكوّن Unity Plugin" فئة AppUpdateManager
لمعالجة الاتصالات بين
تطبيقك وGoogle Play API. يجب إنشاء مثيل لهذه الفئة قبل أن تتمكّن من
استخدامها لإدارة التحديثات داخل التطبيق:
AppUpdateManager appUpdateManager = new AppUpdateManager();
إعداد بيئة التطوير
OpenUPM-CLI
إذا كان لديك واجهة برمجة التطبيقات OpenUPM مثبّتة، يمكنك تثبيت قاعدة بيانات مسجّلي OpenUPM باستخدام الأمر التالي:
openupm add com.google.play.appupdate
OpenUPM
افتح إعدادات مدير الحِزم من خلال اختيار خيار قائمة Unity تعديل > إعدادات المشروع > مدير الحِزم.
أضِف 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
افتح قائمة مدير الحِزم من خلال اختيار خيار قائمة Unity نافذة > مدير الحِزم.
اضبط القائمة المنسدلة لنطاق عمل المدير لاختيار سجلّاتي.
اختَر حزمة Google Play Integrity plugin for Unity من قائمة الحِزم واضغط على تثبيت.
الاستيراد من GitHub
نزِّل أحدث إصدار من
.unitypackage
من GitHub.استورِد ملف
.unitypackage
من خلال اختيار خيار قائمة Unity التالي: مواد العرض > استيراد حزمة > حزمة مخصّصة واستيراد جميع العناصر.
التحقّق من توفّر تحديث
قبل طلب تحديث، تحقّق ممّا إذا كان هناك تحديث متاح لتطبيقك. استخدِم 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". يمكن أن يساعدك ذلك في تحديد ما إذا كان عليك بدء تعديل مرن أو تعديل فوري. على سبيل المثال، يمكنك الانتظار بضعة أيام قبل إشعار المستخدم بتعديل مرن، ثم الانتظار بضعة أيام بعد ذلك قبل طلب إجراء تعديل فوري.
استخدِم 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);
تعتمد الخطوات التالية على ما إذا كنت تطلب تعديلًا مرنًا أو تعديلًا فوريًا.
معالجة تعديل مرن
بعد الحصول على عنصر 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
العنصر يشير إلى أنّ نوع التعديل المحدّد مسموح به قبل بدء عملية التعديل.
الخطوات التالية
اختبِر التحديثات داخل التطبيق للتأكّد من أنّ عملية الدمج تعمل بشكلٍ صحيح.