รองรับการอัปเดตในแอป (Unity)

คู่มือนี้อธิบายวิธีรองรับการอัปเดตในแอปในแอปโดยใช้ Unity มีคำแนะนำแยกต่างหากสำหรับกรณีที่การติดตั้งใช้งานใช้ภาษาโปรแกรม Kotlin หรือภาษาโปรแกรม Java และกรณีที่การติดตั้งใช้งานใช้โค้ดเนทีฟ (C/C++)

ตั้งค่าสภาพแวดล้อมการพัฒนา

OpenUPM-CLI

หากติดตั้ง OpenUPM CLI แล้ว คุณจะติดตั้งรีจิสทรี 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 ชิ้นงาน > นําเข้าแพ็กเกจ > แพ็กเกจที่กําหนดเอง และนําเข้ารายการทั้งหมด

ภาพรวมของ Unity SDK

Play In-App Update API เป็นส่วนหนึ่งของครอบครัว Play Core SDK ปลั๊กอิน Unity มีคลาส AppUpdateManager จัดการการสื่อสารระหว่างแอปกับ Play API คุณต้องสร้างอินสแตนซ์ของคลาสนี้ก่อนจึงจะใช้คลาสนี้เพื่อจัดการการอัปเดตในแอปได้

AppUpdateManager appUpdateManager = new AppUpdateManager();

ตรวจสอบความพร้อมในการอัปเดต

ก่อนขอการอัปเดต ให้ตรวจสอบว่าอัปเดตสำหรับแอปของคุณพร้อมใช้งานหรือไม่ ใช้ AppUpdateManager เพื่อตรวจสอบการอัปเดตใน Coroutine ดังนี้

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 Store ซึ่งจะช่วยให้คุณตัดสินใจได้ว่าจะเริ่มต้นการอัปเดตแบบยืดหยุ่นหรือการอัปเดตทันที เช่น คุณอาจรอ 2-3 วันก่อนแจ้งให้ผู้ใช้อัปเดตแบบยืดหยุ่น และรออีก 2-3 วันหลังจากนั้นก่อนกำหนดให้อัปเดตทันที

ใช้ ClientVersionStalenessDays เพื่อตรวจสอบจำนวนวันที่นับตั้งแต่การอัปเดตพร้อมให้บริการผ่าน Play Store

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

ตรวจสอบลำดับความสำคัญของการอัปเดต

Google Play Developer API ช่วยให้คุณกำหนดลำดับความสำคัญของการอัปเดตแต่ละรายการได้ ซึ่งจะช่วยให้แอปตัดสินใจได้ว่าควรแนะนำให้ผู้ใช้อัปเดตมากน้อยเพียงใด ตัวอย่างเช่น ลองพิจารณากลยุทธ์ต่อไปนี้ในการตั้งค่าลำดับความสำคัญของการอัปเดต

  • การปรับปรุง UI เล็กน้อย: การอัปเดตสำคัญน้อย ไม่ขอการอัปเดตแบบยืดหยุ่นหรือการอัปเดตทันที
  • การปรับปรุงประสิทธิภาพ: การอัปเดตสำคัญปานกลาง ขอการอัปเดตแบบยืดหยุ่น
  • การอัปเดตความปลอดภัยที่สำคัญ: การอัปเดตสำคัญสูง ขอการอัปเดตทันที

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 เป็นค่า Null ตรวจสอบว่าออบเจ็กต์ AppUpdateInfo ที่แสดงผลจาก GetAppUpdateInfo() ไม่ใช่ค่าว่างก่อนเริ่มขั้นตอนการอัปเดต
  • หาก PlayAsyncOperation แสดงรหัสข้อผิดพลาด ErrorUpdateUnavailable ให้ตรวจสอบว่ามีเวอร์ชันแอปที่อัปเดตแล้วซึ่งมี Application ID และคีย์การรับรองเดียวกัน
  • หาก PlayAsyncOperation แสดงรหัสข้อผิดพลาด ErrorUpdateNotAllowed หมายความว่าออบเจ็กต์ AppUpdateOptions ระบุประเภทการอัปเดตที่ไม่อนุญาตให้อัปเดต ตรวจสอบว่าออบเจ็กต์ AppUpdateInfo ระบุว่าอนุญาตให้อัปเดตประเภทที่เลือกหรือไม่ก่อนที่จะเริ่มขั้นตอนการอัปเดต

ขั้นตอนถัดไป

ทดสอบการอัปเดตในแอปของแอปเพื่อยืนยันว่าการผสานรวมทํางานได้อย่างถูกต้อง