Bagikan melalui


Cordova Client SDK

Penting

Visual Studio App Center dijadwalkan untuk dihentikan pada 31 Maret 2025. Meskipun Anda dapat terus menggunakan Visual Studio App Center hingga sepenuhnya dihentikan, ada beberapa alternatif yang direkomendasikan yang dapat Anda pertimbangkan untuk bermigrasi.

Pelajari selengkapnya tentang garis waktu dukungan dan alternatif.

Plugin ini menyediakan integrasi sisi klien untuk layanan CodePush, memungkinkan Anda untuk dengan mudah menambahkan pengalaman pembaruan dinamis ke aplikasi Cordova Anda.

Catatan

Dukungan untuk Aplikasi Cordova telah berakhir pada April 2022. Temukan informasi selengkapnya di blog App Center.

Bagaimana cara kerjanya?

Aplikasi Cordova terdiri dari file HTML, CSS, dan JavaScript dan gambar yang menyertainya, yang dibundel bersama oleh Cordova CLI dan didistribusikan sebagai bagian dari biner khusus platform (yaitu file .ipa atau .apk). Setelah aplikasi dirilis, memperbarui kode atau aset gambar mengharuskan Anda untuk mengkompilasi ulang dan mendistribusikan ulang seluruh biner. Proses ini mencakup waktu peninjauan untuk penyimpanan yang Anda terbitkan.

Plugin CodePush membantu mendapatkan peningkatan produk di depan pengguna akhir Anda secara instan, dengan menjaga kode dan gambar Anda tetap sinkron dengan pembaruan yang Anda rilis ke server CodePush. Dengan cara ini, aplikasi Anda mendapatkan manfaat dari pengalaman seluler offline, serta kelincahan "seperti web" pembaruan pemuatan samping segera setelah tersedia. Ini sama-sama menguntungkan!

Untuk memastikan bahwa pengguna akhir Anda selalu memiliki versi aplikasi yang berfungsi, plugin CodePush mempertahankan salinan pembaruan sebelumnya, sehingga jika Anda secara tidak sengaja mendorong pembaruan yang menyertakan crash, itu dapat secara otomatis digulung balik. Dengan cara ini, Anda dapat yakin bahwa kelincahan rilis baru Anda tidak akan mengakibatkan pengguna diblokir sebelum Anda memiliki kesempatan untuk kembali di server. Ini win-win-win!

Catatan

Setiap perubahan produk yang menyentuh kode asli (misalnya meningkatkan versi Cordova, menambahkan plugin baru) tidak dapat didistribusikan melalui CodePush, dan karenanya, harus diperbarui melalui penyimpanan yang sesuai.

Platform Cordova yang Didukung

Cordova 5.0.0+ didukung penuh, bersama dengan platform terkait berikut:

Untuk memeriksa versi setiap platform Cordova yang saat ini Anda gunakan, Anda dapat menjalankan perintah berikut dan memeriksa Installed platforms daftar:

    cordova platform ls

Jika Anda menjalankan platform Android atau iOS yang lebih lama dari yang disebutkan di atas, dan akan terbuka untuk meningkatkan versi, Anda dapat dengan mudah melakukannya dengan menjalankan perintah berikut (menghilangkan platform jika tidak diperlukan):

    cordova platform update android
    cordova platform update ios

Memulai

Catatan

Artikel ini berisi referensi ke daftar putih istilah, istilah yang tidak lagi digunakan Microsoft. Saat istilah tersebut dihapus dari perangkat lunak, kami akan menghapusnya dari artikel ini.

Setelah mengikuti instruksi "memulai" tujuan umum untuk menyiapkan akun CodePush, Anda dapat memulai CodePush-ifying aplikasi Cordova Anda dengan menjalankan perintah berikut dari dalam direktori akar aplikasi Anda:

cordova plugin add cordova-plugin-code-push@latest

Dengan plugin CodePush terinstal, konfigurasikan aplikasi Anda untuk menggunakannya melalui langkah-langkah berikut:

  1. Tambahkan kunci penyebaran Anda ke file config.xml , pastikan untuk menyertakan kunci yang tepat untuk setiap platform Cordova:
    <platform name="android">
        <preference name="CodePushDeploymentKey" value="YOUR-ANDROID-DEPLOYMENT-KEY" />
    </platform>
    <platform name="ios">
        <preference name="CodePushDeploymentKey" value="YOUR-IOS-DEPLOYMENT-KEY" />
    </platform>

Sebagai pengingat, kunci ini dibuat untuk Anda saat Anda membuat aplikasi CodePush melalui CLI. Jika Anda perlu mengambilnya, Anda dapat menjalankan appcenter codepush deployment list -a <ownerName>/<appName> --displayKeys, dan mengambil kunci untuk penyebaran tertentu yang ingin Anda gunakan (misalnya Staging, Production).

Penting

Sebaiknya buat aplikasi CodePush terpisah untuk iOS dan Android, itulah sebabnya sampel di atas mendeklarasikan kunci terpisah untuk Android dan iOS. Jika Anda hanya mengembangkan untuk satu platform, maka Anda hanya perlu menentukan kunci penyebaran untuk Android atau iOS, jadi Anda tidak perlu menambahkan elemen tambahan <platform> seperti yang diilustrasikan di atas.

Mulai dari versi 1.10.0 Anda dapat menandatangani bundel pembaruan Anda (untuk informasi selengkapnya tentang penandatanganan kode, lihat bagian dokumentasi yang relevan). Untuk mengaktifkan penandatanganan kode untuk aplikasi Cordova, Anda harus menyiapkan kunci umum untuk memverifikasi tanda tangan bundel dengan menyediakan pengaturan berikut preference di config.xml:

    <platform name="android">
        ...
        <preference name="CodePushPublicKey" value="YOUR-PUBLIC-KEY" />
    </platform>
    <platform name="ios">
        ...
        <preference name="CodePushPublicKey" value="YOUR-PUBLIC-KEY" />
    </platform>

Anda dapat menggunakan pasangan kunci privat/publik yang sama untuk setiap platform.

  1. Jika Anda menggunakan <access origin="*" /> elemen dalam file config.xml , maka aplikasi Anda sudah diizinkan untuk berkomunikasi dengan server CodePush dan Anda dapat melewati langkah ini dengan aman. Jika tidak, tambahkan elemen tambahan <access /> berikut:
    <access origin="https://codepush.appcenter.ms" />
    <access origin="https://codepush.blob.core.windows.net" />
    <access origin="https://codepushupdates.azureedge.net" />
  1. Untuk memastikan bahwa aplikasi Anda dapat mengakses server CodePush di platform yang mematuhi CSP, tambahkan https://codepush.appcenter.ms ke Content-Security-Policymeta tag di file Anda index.html :
    <meta http-equiv="Content-Security-Policy" content="default-src https://codepush.appcenter.ms 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *" />
  1. Terakhir, periksa kembali apakah Anda sudah menginstal cordova-plugin-whitelist plugin (sebagian besar aplikasi akan). Untuk memeriksa hal ini, jalankan perintah berikut:
    cordova plugin ls    

Jika cordova-plugin-whitelist ada dalam daftar, maka Anda baik untuk pergi. Jika tidak, jalankan perintah berikut untuk menambahkannya:

    cordova plugin add cordova-plugin-whitelist

Anda sekarang siap untuk menggunakan plugin dalam kode aplikasi. Lihat contoh aplikasi untuk contoh dan dokumentasi API untuk detail selengkapnya.

Penggunaan Plugin

Dengan plugin CodePush diinstal dan dikonfigurasi, satu-satunya hal yang tersisa adalah menambahkan kode yang diperlukan ke aplikasi Anda untuk mengontrol kebijakan berikut:

  1. Kapan (dan seberapa sering) memeriksa pembaruan? (e.g. app mulai, sebagai respons terhadap mengklik tombol di halaman pengaturan, secara berkala pada beberapa interval tetap)
  2. Saat pembaruan tersedia, bagaimana cara menyajikannya kepada pengguna akhir? Cara paling sederhana untuk melakukan ini adalah dengan menjalankan hal berikut di penanganan aktivitas aplikasi deviceready Anda:
codePush.sync();

Jika pembaruan tersedia, pembaruan akan diunduh secara diam-diam, dan diinstal saat berikutnya aplikasi dimulai ulang (baik secara eksplisit oleh pengguna akhir atau oleh OS), yang memastikan pengalaman yang paling tidak invasif untuk pengguna akhir Anda. Jika pembaruan yang tersedia wajib, maka akan segera diinstal, memastikan bahwa pengguna akhir mendapatkannya sesegera mungkin.

Jika Anda ingin aplikasi menemukan pembaruan dengan lebih cepat, Anda juga dapat memilih untuk memanggil sync setiap kali aplikasi dilanjutkan dari latar belakang, dengan menambahkan kode berikut (atau sesuatu yang setara) sebagai bagian dari perilaku startup aplikasi Anda. Anda dapat memanggil sync sesering yang Anda inginkan, jadi kapan dan di mana Anda memanggilnya tergantung pada preferensi pribadi Anda.

document.addEventListener("resume", function () {
    codePush.sync();
});

Selain itu, jika Anda ingin menampilkan dialog konfirmasi pembaruan ("penginstalan aktif"), konfigurasikan kapan pembaruan yang tersedia diinstal (misalnya paksa hidupkan ulang segera) atau sesuaikan pengalaman pembaruan dengan cara apa pun, lihat sync referensi API metode untuk informasi tentang cara mengubah perilaku default ini.

Penting

Meskipun perjanjian pengembang Apple sepenuhnya memungkinkan pembaruan JavaScript dan aset over-the-air (yang memungkinkan CodePush!), itu melanggar kebijakan mereka agar aplikasi menampilkan perintah pembaruan. Karena itu, kami menyarankan agar aplikasi yang didistribusikan App Store tidak mengaktifkan updateDialog opsi saat memanggil sync, sedangkan Google Play dan aplikasi yang didistribusikan secara internal (misalnya Enterprise, Fabric, HockeyApp) dapat memilih untuk mengaktifkan/menyesuaikannya.

Melepaskan Updates

Setelah aplikasi Anda dikonfigurasi dan didistribusikan kepada pengguna Anda, dan Anda telah membuat beberapa perubahan kode atau aset, saatnya untuk langsung merilisnya! Cara paling sederhana (dan disarankan) untuk melakukan ini adalah dengan menggunakan release-cordova perintah di CodePush CLI, yang menangani persiapan dan merilis pembaruan Anda ke server CodePush.

Catatan

Sebelum Anda dapat mulai merilis pembaruan, masuk ke App Center dengan menjalankan appcenter login perintah

Dalam bentuk yang paling dasar, perintah ini hanya memerlukan satu parameter: nama pemilik Anda + "/" + nama aplikasi.

appcenter codepush release-cordova -a <ownerName>/<appName>
appcenter codepush release-cordova -a <ownerName>/MyApp-ios
appcenter codepush release-cordova -a <ownerName>/MyApp-android

Tip

Dengan menggunakan fungsi CLI set-current App Center, Anda tidak perlu menggunakan bendera -a untuk menentukan aplikasi tempat perintah diarahkan.

Tip

Saat merilis pembaruan ke CodePush, Anda tidak perlu menabrak versi aplikasi di file config.xml , karena Anda tidak memodifikasi versi biner sama sekali. Anda hanya perlu menabrak versi ini ketika Anda meningkatkan Cordova atau salah satu plugin Anda, di mana Anda perlu merilis pembaruan ke toko asli. CodePush akan secara otomatis menghasilkan "label" untuk setiap rilis yang Anda buat (misalnya v3) untuk membantu mengidentifikasinya dalam riwayat rilis Anda.

Perintah ini release-cordova memungkinkan alur kerja sederhana seperti itu karena memahami tata letak standar aplikasi Cordova, sehingga, dapat menghasilkan pembaruan Anda dan mengetahui dengan tepat file mana yang akan diunggah. Selain itu, untuk mendukung strategi rilis yang fleksibel, release-cordova perintah mengekspos banyak parameter opsional yang memungkinkan Anda menyesuaikan bagaimana pembaruan harus didistribusikan ke pengguna akhir Anda (misalnya versi biner mana yang kompatibel dengannya? Haruskah rilis dilihat sebagai wajib?).

# Release a mandatory update with a changelog
appcenter codepush release-cordova -a <ownerName>/MyApp-ios -m --description "Modified the header color"

# Release a dev Android build to 1/4 of your end users
appcenter codepush release-cordova -a <ownerName>/MyApp-android --rollout 25

# Release an update that targets users running any 1.1.* binary, as opposed to
# limiting the update to exact version name in the config.xml file
appcenter codepush release-cordova -a <ownerName>/MyApp-android --target-binary-version "~1.1.0"

# Release the update now but mark it as disabled
# so that no users can download it yet
appcenter codepush release-cordova -a <ownerName>/MyApp-ios -x

Klien CodePush mendukung pembaruan diferensial, jadi meskipun Anda merilis kode aplikasi pada setiap pembaruan, pengguna akhir Anda hanya akan benar-benar mengunduh file yang mereka butuhkan. Layanan ini menangani ini secara otomatis sehingga Anda dapat fokus pada pembuatan aplikasi yang luar biasa dan kami dapat khawatir tentang mengoptimalkan unduhan pengguna akhir.

Untuk detail selengkapnya tentang cara release-cordova kerja perintah, serta berbagai parameter yang dieksposnya, lihat dokumen CLI. Selain itu, jika Anda lebih suka menjalankan cordova prepare perintah sendiri, dan karenanya, menginginkan solusi yang lebih fleksibel daripada release-cordova, lihat release perintah untuk detail selengkapnya.

Jika Anda mengalami masalah, atau memiliki pertanyaan/komentar/umpan balik, Anda dapat mengirim email kepada kami atau membuka masalah baru pada repositori ini dan kami akan merespons secepatnya! Lihat juga bantuan dan umpan balik.

Referensi API

CODEPush API diekspos ke aplikasi Anda melalui objek global codePush , yang tersedia setelah deviceready peristiwa diaktifkan. API ini memaparkan metode tingkat atas berikut:

  • checkForUpdate: Menanyakan layanan CodePush apakah penyebaran aplikasi yang dikonfigurasi memiliki pembaruan yang tersedia.
  • getCurrentPackage: Mengambil metadata tentang pembaruan yang saat ini diinstal (misalnya deskripsi, waktu penginstalan, ukuran).
  • getPendingPackage: Mengambil metadata untuk pembaruan (jika ada) yang diunduh dan diinstal, tetapi belum diterapkan melalui mulai ulang.
  • notifyApplicationReady: Memberi tahu runtime CodePush bahwa pembaruan yang diinstal dianggap berhasil. Jika Anda memeriksa dan menginstal pembaruan secara manual (yaitu tidak menggunakan metode sinkronisasi untuk menangani semuanya untuk Anda), maka metode ini HARUS dipanggil; jika tidak, CodePush akan memperlakukan pembaruan sebagai gagal dan kembali ke versi sebelumnya saat aplikasi berikutnya dimulai ulang.
  • restartApplication: Segera memulai ulang aplikasi. Jika ada pembaruan yang tertunda, pembaruan akan segera ditampilkan kepada pengguna akhir.
  • sync: Memungkinkan pemeriksaan pembaruan, mengunduhnya dan menginstalnya, semuanya dengan satu panggilan. Kecuali Anda memerlukan UI atau perilaku kustom, kami menyarankan sebagian besar pengembang untuk menggunakan metode ini saat mengintegrasikan CodePush ke dalam aplikasi mereka.

Selain itu, objek dan enum berikut juga diekspos secara global sebagai bagian dari CODEPush API:

  • InstallMode: Menentukan mode penginstalan yang tersedia untuk pembaruan.
  • LocalPackage: Berisi informasi tentang paket yang diinstal secara lokal.
  • RemotePackage: Berisi informasi tentang paket pembaruan yang tersedia untuk diunduh.
  • SyncStatus: Menentukan kemungkinan status perantara dan hasil operasi sinkronisasi .

codePush.checkForUpdate

codePush.checkForUpdate(onSuccess, onError?, deploymentKey?: String);

Mengkueri layanan CodePush untuk melihat apakah penyebaran aplikasi yang dikonfigurasi memiliki pembaruan yang tersedia. Secara default, ini akan menggunakan kunci penyebaran yang dikonfigurasi dalam file config.xml Anda, tetapi Anda dapat mengambil alihnya dengan menentukan nilai melalui parameter opsional deploymentKey . Ini dapat berguna ketika Anda ingin secara dinamis "mengalihkan" pengguna ke penyebaran tertentu, seperti mengizinkan "Akses awal" melalui telur paskah atau sakelar pengaturan pengguna.

Ketika pemeriksaan pembaruan selesai, itu akan memicu onUpdateCheck panggilan balik dengan salah satu dari dua nilai yang mungkin:

  1. null jika tidak ada pembaruan yang tersedia. Ini terjadi dalam skenario berikut:
    • Penyebaran yang dikonfigurasi tidak berisi rilis apa pun, jadi tidak ada yang perlu diperbarui.
    • Rilis terbaru dalam penyebaran yang dikonfigurasi menargetkan versi biner yang berbeda dari yang saat ini Anda jalankan (baik yang lebih lama atau yang lebih baru).
    • Aplikasi yang sedang berjalan sudah memiliki rilis terbaru dari penyebaran yang dikonfigurasi, sehingga tidak memerlukan rilis lagi.
  2. RemotePackage Instans yang mewakili pembaruan yang tersedia yang dapat diperiksa dan kemudian diunduh.

Parameter:

  • onSuccess: Panggilan balik yang dipanggil setelah menerima respons yang berhasil dari server. Panggilan balik menerima satu parameter, yang dijelaskan di atas.
  • onError: Panggilan balik opsional yang dipanggil jika terjadi kesalahan. Panggilan balik mengambil satu parameter kesalahan, yang berisi detail kesalahan.
  • deploymentKey: Kunci penyebaran opsional yang mengambil alih pengaturan config.xml .

Contoh penggunaan:

codePush.checkForUpdate(function (update) {
    if (!update) {
        console.log("The app is up to date.");
    } else {
        console.log("An update is available! Should we download it?");
    }
});

codePush.getCurrentPackage

codePush.getCurrentPackage(onSuccess, onError?);

Mengambil metadata tentang "paket" yang saat ini diinstal (misalnya deskripsi, waktu penginstalan). Ini dapat berguna untuk skenario seperti menampilkan dialog "apa yang baru?" setelah pembaruan diterapkan atau memeriksa apakah ada pembaruan tertunda yang menunggu untuk diterapkan melalui resume atau restart.

Ketika pengambilan pembaruan selesai, itu akan memicu onSuccess panggilan balik dengan salah satu dari dua nilai yang mungkin:

  1. null jika aplikasi saat ini menjalankan halaman mulai HTML dari biner dan bukan pembaruan CodePush. Ini terjadi dalam skenario berikut:
    • Pengguna akhir menginstal biner aplikasi dan belum menginstal pembaruan CodePush
    • Pengguna akhir menginstal pembaruan biner (misalnya dari penyimpanan), yang menghapus pembaruan CodePush lama, dan memberikan prioritas kembali ke biner.
  2. LocalPackage Instans yang mewakili metadata untuk pembaruan CodePush yang sedang berjalan.

Parameter:

  • onSuccess: Panggilan balik yang dipanggil saat menerima metadata tentang pembaruan yang sedang berjalan. Panggilan balik menerima satu parameter, yang dijelaskan di atas.
  • onError: Panggilan balik opsional yang dipanggil jika terjadi kesalahan. Panggilan balik mengambil satu parameter kesalahan, yang berisi detail kesalahan.

Contoh Penggunaan:

codePush.getCurrentPackage(function (update) {
    if (!update) {
        console.log("No updates have been installed");
        return;
    }

    // If the current app "session" represents the first time
    // this update has run, and it had a description provided
    // with it upon release, let's show it to the end user
    if (update.isFirstRun && update.description) {
        // Display a "what's new?" modal
    }
});

codePush.getPendingPackage

codePush.getPendingPackage(onSuccess, onError?);

Mendapatkan metadata untuk pembaruan yang saat ini tertunda (jika ada). Pembaruan dianggap "tertunda" jika telah diunduh dan diinstal, tetapi belum diterapkan melalui mulai ulang aplikasi. Pembaruan hanya dapat berada dalam status ini jika InstallMode.ON_NEXT_RESTART atau InstallMode.ON_NEXT_RESUME ditentukan saat memanggil sync atau LocalPackage.install, dan aplikasi belum dimulai ulang atau dilanjutkan (masing-masing). Metode ini dapat berguna jika Anda ingin menentukan apakah ada pembaruan yang tertunda dan kemudian meminta pengguna jika mereka ingin segera memulai ulang (melalui codePush.restartApplication) untuk menerapkannya.

Ketika pengambilan pembaruan selesai, itu akan memicu onSuccess panggilan balik dengan salah satu dari dua nilai yang mungkin:

  1. null jika aplikasi saat ini tidak memiliki pembaruan yang tertunda (misalnya, aplikasi sudah menjalankan versi terbaru yang tersedia).
  2. LocalPackage Instans yang mewakili metadata untuk pembaruan CodePush yang saat ini tertunda.

Parameter:

  • onSuccess: Panggilan balik yang dipanggil saat menerima metadata tentang pembaruan yang saat ini tertunda. Panggilan balik menerima satu parameter, yang dijelaskan di atas.
  • onError: Panggilan balik opsional yang dipanggil jika terjadi kesalahan. Panggilan balik mengambil satu parameter kesalahan, yang berisi detail kesalahan.

Contoh Penggunaan:

codePush.getPendingPackage(function (update) {
    if (update) {
        // An update is currently pending, ask the
        // user if they want to restart
    }
});

codePush.notifyApplicationReady

codePush.notifyApplicationReady(notifySucceeded?, notifyFailed?);

Memberi tahu runtime CodePush bahwa pembaruan yang baru diinstal harus dianggap berhasil, sehingga rollback sisi klien otomatis tidak diperlukan. Anda harus memanggil fungsi ini di suatu tempat dalam kode bundel yang diperbarui. Jika tidak, ketika aplikasi berikutnya dimulai ulang, runtime CodePush akan mengasumsikan bahwa pembaruan yang diinstal telah gagal dan kembali ke versi sebelumnya. Perilaku ini ada untuk membantu memastikan bahwa pengguna akhir Anda tidak diblokir oleh pembaruan yang rusak.

Jika Anda menggunakan sync fungsi , dan melakukan pemeriksaan pembaruan pada aplikasi dimulai, maka Anda tidak perlu memanggilnya notifyApplicationReady secara manual karena sync akan memanggilnya untuk Anda. Perilaku ini ada karena asumsi bahwa ketika sync dipanggil di aplikasi Anda mewakili perkiraan yang baik dari startup yang berhasil.

Parameter:

  • notifySucceeded: Panggilan balik opsional dipanggil jika plugin berhasil diberi tahu.
  • notifyFailed: Panggilan balik opsional dipanggil jika ada kesalahan yang memberi tahu plugin.

codePush.restartApplication

codePush.restartApplication();

Segera memulai ulang aplikasi. Metode ini untuk skenario lanjutan, dan terutama berguna ketika kondisi berikut ini benar:

  1. Aplikasi Anda menentukan nilai ON_NEXT_RESTART mode penginstalan atau ON_NEXT_RESUME saat memanggil sync metode atau LocalPackage.install . Ini tidak menerapkan pembaruan Anda hingga aplikasi dimulai ulang (oleh pengguna akhir atau OS) atau dilanjutkan, sehingga pembaruan tidak akan segera ditampilkan kepada pengguna akhir.
  2. Anda memiliki peristiwa pengguna khusus aplikasi (misalnya pengguna akhir yang dinavigasi kembali ke rute rumah aplikasi) yang memungkinkan Anda menerapkan pembaruan dengan cara yang tidak mengganggu, dan berpotensi mendapatkan pembaruan di depan pengguna akhir lebih cepat daripada menunggu hingga mulai ulang atau lanjutkan berikutnya.

codePush.sync

codePush.sync(syncCallback?, syncOptions?, downloadProgress?, syncErrback?);

Menyinkronkan kode dan gambar aplikasi Anda dengan rilis terbaru ke penyebaran yang dikonfigurasi. checkForUpdate Tidak seperti metode , yang memeriksa keberadaan pembaruan, dan memungkinkan Anda mengontrol apa yang harus dilakukan selanjutnya, sync menangani pemeriksaan pembaruan, pengunduhan, dan pengalaman penginstalan untuk Anda.

Metode ini menyediakan dukungan untuk dua "mode" yang berbeda (tetapi dapat disesuaikan) untuk dengan mudah mengaktifkan aplikasi dengan persyaratan yang berbeda:

  1. Mode senyap(perilaku default), yang secara otomatis mengunduh pembaruan yang tersedia, dan menerapkannya saat aplikasi dimulai ulang di lain waktu (misalnya OS atau pengguna akhir mematikannya, atau perangkat dimulai ulang). Dengan cara ini, seluruh pengalaman pembaruan "diam" untuk pengguna akhir, karena mereka tidak melihat perintah pembaruan atau mulai ulang aplikasi "sintetis".
  2. Mode aktif, yang ketika pembaruan tersedia, meminta izin kepada pengguna akhir sebelum mengunduhnya, lalu segera menerapkan pembaruan. Jika pembaruan dirilis menggunakan bendera wajib, pengguna akhir masih akan diberi tahu tentang pembaruan, tetapi mereka tidak akan memiliki pilihan untuk mengabaikannya.

Contoh Penggunaan:

// Fully silent update that keeps the app in
// sync with the server, without ever
// interrupting the end user
codePush.sync();

// Active update that lets the end user know
// about each update, and displays it to them
// immediately after downloading it
codePush.sync(null, { updateDialog: true, installMode: InstallMode.IMMEDIATE });

Tip

Jika Anda ingin memutuskan apakah Anda memeriksa atau mengunduh pembaruan yang tersedia berdasarkan tingkat baterai perangkat pengguna akhir, kondisi jaringan, dll. kemudian bungkus panggilan untuk disinkronkan dalam kondisi yang memastikan Anda hanya memanggilnya saat diinginkan.

Meskipun metode sinkronisasi mencoba memudahkan untuk melakukan pembaruan senyap dan aktif dengan sedikit konfigurasi, metode ini menerima parameter opsional berikut yang memungkinkan Anda menyesuaikan banyak aspek perilaku default yang disebutkan di atas:

  • syncCallback: Dipanggil saat proses sinkronisasi berpindah dari satu tahap ke tahap lainnya dalam proses pembaruan keseluruhan. Metode ini dipanggil dengan kode status yang mewakili status saat ini, dan dapat menjadi salah SyncStatus satu nilai.
  • syncOptions: Parameter opsional SyncOptions yang mengonfigurasi perilaku operasi sinkronisasi.
  • downloadProgress: Dipanggil secara berkala ketika pembaruan yang tersedia sedang diunduh dari server CodePush. Metode ini dipanggil dengan DownloadProgress objek , yang berisi dua properti berikut:
    • totalBytes(Number) - Jumlah total byte yang diharapkan diterima untuk pembaruan ini (yaitu ukuran kumpulan file yang berubah dari rilis sebelumnya).
    • receivedBytes(Number) - Jumlah byte yang diunduh sejauh ini, yang dapat digunakan untuk melacak kemajuan pengunduhan.
  • syncErrback: Dipanggil saat ada kesalahan dalam salah satu langkah internal sinkronisasi. Metode ini disebut dengan objek javascript Error standar sebagai argumen pertama.

SyncOptions

sync Meskipun metode ini mencoba mempermudah untuk melakukan pembaruan senyap dan aktif dengan sedikit konfigurasi, metode ini menerima objek "opsi" yang memungkinkan Anda menyesuaikan banyak aspek perilaku default yang disebutkan di atas:

  • deploymentKey(String) - Menentukan kunci penyebaran yang ingin Anda kueri untuk pembaruan. Secara default, nilai ini berasal dari file config.xml , tetapi opsi ini memungkinkan Anda untuk mengambil alihnya dari sisi skrip jika Anda perlu menggunakan penyebaran yang berbeda secara dinamis untuk panggilan tertentu ke sync.
  • installMode(InstallMode) - Menentukan kapan Anda ingin menginstal pembaruan opsional (yaitu yang tidak ditandai sebagai wajib). Default ke InstallMode.ON_NEXT_RESTART. InstallMode Lihat referensi enum untuk deskripsi opsi yang tersedia dan apa yang mereka lakukan.
  • mandatoryInstallMode(InstallMode) - Menentukan kapan Anda ingin menginstal pembaruan yang ditandai sebagai wajib. Default ke InstallMode.IMMEDIATE. InstallMode Lihat referensi enum untuk deskripsi opsi yang tersedia dan apa yang mereka lakukan.
  • minimumBackgroundDuration(Number) - Menentukan jumlah detik minimum agar aplikasi berada di latar belakang sebelum memulai ulang aplikasi. Properti ini hanya berlaku untuk pembaruan yang diinstal menggunakan InstallMode.ON_NEXT_RESUME, dan dapat berguna untuk mendapatkan pembaruan Anda di depan pengguna akhir lebih cepat, tanpa terlalu mengganggu. Default ke 0, yang menerapkan pembaruan segera setelah resume, namun lama di latar belakang.
  • ignoreFailedUpdates(Boolean) - Menentukan apakah pembaruan yang tersedia harus diabaikan jika sebelumnya telah diinstal dan digulung balik pada klien (karena notifyApplicationReady tidak berhasil dipanggil). Default ke true.
  • updateDialog(UpdateDialogOptions) - Objek "opsi" yang digunakan untuk menentukan apakah dialog konfirmasi harus ditampilkan kepada pengguna akhir saat pembaruan tersedia, dan jika demikian, string apa yang akan digunakan. Default ke null, yang menonaktifkan dialog. Mengatur ini ke nilai apa pun true akan mengaktifkan dialog dengan string default, dan meneruskan objek ke parameter ini memungkinkan pengaktifan dialog serta menimpa satu atau beberapa string default.

Daftar berikut ini mewakili opsi yang tersedia dan defaultnya:

  • appendReleaseDescription(Boolean) - Menunjukkan apakah Anda ingin menambahkan deskripsi rilis yang tersedia ke pesan pemberitahuan yang ditampilkan kepada pengguna akhir. Default ke false.
  • descriptionPrefix(String) - Menunjukkan string yang ingin Anda awali deskripsi rilisnya, jika ada, saat menampilkan pemberitahuan pembaruan kepada pengguna akhir. Default ke " Description: ".
  • mandatoryContinueButtonLabel(String): Teks yang digunakan untuk tombol yang harus ditekan pengguna akhir untuk menginstal pembaruan wajib. Default ke "Continue".
  • mandatoryUpdateMessage(String) - Teks yang digunakan sebagai isi pemberitahuan pembaruan, saat pembaruan ditentukan sebagai wajib. Default ke "An update is available that must be installed.".
  • optionalIgnoreButtonLabel(String) - Teks yang digunakan untuk tombol yang dapat ditekan pengguna akhir untuk mengabaikan pembaruan opsional yang tersedia. Default ke "Ignore".
  • optionalInstallButtonLabel(String) - Teks yang digunakan untuk tombol yang dapat ditekan pengguna akhir untuk menginstal pembaruan opsional. Default ke "Install".
  • optionalUpdateMessage(String) - Teks yang digunakan sebagai isi pemberitahuan pembaruan, saat pembaruan bersifat opsional. Default ke "An update is available. Would you like to install it?". *- updateTitle(String) - Teks yang digunakan sebagai header pemberitahuan pembaruan yang ditampilkan kepada pengguna akhir. Default ke "Update available".

Contoh Penggunaan:

// Download the update silently, but install it on
// the next resume, as long as at least 5 minutes
// has passed since the app was put into the background.
codePush.sync(null, { installMode: InstallMode.ON_NEXT_RESUME, minimumBackgroundDuration: 60 * 5 });

// Download the update silently, and install optional updates
// on the next restart, but install mandatory updates on the next resume.
codePush.sync(null, { mandatoryInstallMode: InstallMode.ON_NEXT_RESUME });

// Changing the title displayed in the
// confirmation dialog of an "active" update
codePush.sync(null, { updateDialog: { title: "An update is available!" } });

// Displaying an update prompt that includes the
// description for the CodePush release
codePush.sync(null, {
   updateDialog: {
    appendReleaseDescription: true,
    descriptionPrefix: "\n\nChange log:\n"
   },
   installMode: InstallMode.IMMEDIATE
});

// Silently check for the update, but
// display a custom downloading UI
// via the SyncStatus and DownloadProgress callbacks
codePush.sync(syncStatus, null, downloadProgress);

function syncStatus(status) {
    switch (status) {
        case SyncStatus.DOWNLOADING_PACKAGE:
            // Show "downloading" modal
            break;
        case SyncStatus.INSTALLING_UPDATE:
            // Hide "downloading" modal
            break;
    }
}

function downloadProgress(downloadProgress) {
    if (downloadProgress) {
    	// Update "downloading" modal with current download %
        //console.log("Downloading " + downloadProgress.receivedBytes + " of " + downloadProgress.totalBytes);
    }
}

Metode sync ini dapat dipanggil di mana saja Anda ingin memeriksa pembaruan. Itu bisa berada di deviceready penanganan aktivitas, click peristiwa tombol, dalam panggilan balik timer berkala, atau apa pun yang masuk akal untuk kebutuhan Anda. Seperti metode , checkForUpdate metode ini akan menjalankan permintaan jaringan untuk memeriksa pembaruan di latar belakang, sehingga tidak akan berdampak pada utas UI atau responsivitas utas JavaScript Anda.

Objek paket

Metode checkForUpdate dan getCurrentPackage memanggil panggilan balik keberhasilan, yang ketika dipicu, menyediakan akses ke objek "paket". Paket mewakili pembaruan kode Anda serta metadata tambahan (misalnya deskripsi, wajib?). CODEPush API memiliki perbedaan antara jenis paket berikut:

  1. LocalPackage: Mewakili pembaruan yang diunduh yang sudah berjalan, atau telah diinstal dan tertunda memulai ulang aplikasi.
  2. RemotePackage: Mewakili pembaruan yang tersedia di server CodePush yang belum diunduh.

LocalPackage

Berisi detail tentang pembaruan yang telah diunduh secara lokal atau sudah diinstal. Anda bisa mendapatkan referensi ke instans objek ini baik dengan memanggil codePush.getCurrentPackage metode , atau sebagai nilai yang diberikan untuk panggilan balik RemotePackage.download keberhasilan metode .

Properti
  • appVersion: Versi asli aplikasi yang ditujukan untuk pembaruan paket ini. (String)
  • deploymentKey: Kunci penyebaran paket. (String)
  • deskripsi: Deskripsi pembaruan. Ini adalah nilai yang sama dengan yang Anda tentukan di CLI saat Anda merilis pembaruan. (String)
  • failedInstall: Menunjukkan apakah pembaruan ini telah diinstal sebelumnya tetapi digulung balik. Metode ini sync akan secara otomatis mengabaikan pembaruan yang sebelumnya gagal, jadi Anda hanya perlu khawatir tentang properti ini jika menggunakan checkForUpdate. (Boolean)
  • isFirstRun: Bendera yang menunjukkan apakah eksekusi aplikasi saat ini adalah yang pertama setelah paket diterapkan. (Boolean)
  • isMandatory: Menunjukkan apakah pembaruan dianggap wajib. Ini adalah nilai yang ditentukan dalam CLI ketika pembaruan dirilis. (Boolean)
  • label: Label internal secara otomatis diberikan ke pembaruan oleh server CodePush, seperti v5. Nilai ini secara unik mengidentifikasi pembaruan dalam penyebarannya. (String)
  • packageHash: Nilai hash SHA dari pembaruan. (String)
  • packageSize: Ukuran kode yang terkandung dalam pembaruan, dalam byte. (Angka)
Metode
  • install(installSuccess, installError, installOptions): Menginstal paket ini ke aplikasi. Perilaku penginstalan tergantung pada yang disediakan installOptions. Secara default, paket pembaruan diinstal secara diam-diam dan aplikasi dimuat ulang dengan konten baru pada awal aplikasi berikutnya. Pada eksekusi pertama setelah pembaruan, aplikasi akan menunggu codePush.notifyApplicationReady() panggilan. Setelah panggilan ini dilakukan, operasi penginstalan dianggap berhasil. Jika tidak, operasi penginstalan akan ditandai sebagai gagal, dan aplikasi dikembalikan ke versi sebelumnya pada eksekusi berikutnya.
InstallOptions

Antarmuka yang menentukan beberapa opsi untuk menyesuaikan perilaku operasi penginstalan.

  • installMode: Digunakan untuk menentukan InstallMode yang digunakan untuk operasi penginstalan. Default ke InstallMode.ON_NEXT_RESTART.
  • mandatoryInstallMode: Digunakan untuk menentukan InstallMode yang digunakan untuk operasi penginstalan jika paket wajib. Default ke InstallMode.IMMEDIATE.
  • minimumBackgroundDuration: Jika installMode adalah InstallMode.ON_NEXT_RESUME, digunakan untuk menentukan jumlah waktu aplikasi harus berada di latar belakang sebelum pembaruan diinstal saat dilanjutkan. Default ke 0.

Contoh Penggunaan:

// App version 1 (current version)

var onError = function (error) {
    console.log("An error occurred. " + error);
};

var onInstallSuccess = function () {
    console.log("Installation succeeded.");
};

var onPackageDownloaded = function (localPackage) {
    // Install regular updates after someone navigates away from the app for more than 2 minutes
    // Install mandatory updates after someone restarts the app
    localPackage.install(onInstallSuccess, onError, { installMode: InstallMode.ON_NEXT_RESUME, minimumBackgroundDuration: 120, mandatoryInstallMode: InstallMode.ON_NEXT_RESTART });
};

var onUpdateCheck = function (remotePackage) {
    if (!remotePackage) {
        console.log("The application is up to date.");
    } else {
        // The hash of each previously reverted package is stored for later use.
        // This way, we avoid going into an infinite bad update/revert loop.
        if (!remotePackage.failedInstall) {
            console.log("A CodePush update is available. Package hash: " + remotePackage.packageHash);
            remotePackage.download(onPackageDownloaded, onError);
        } else {
            console.log("The available update was attempted before and failed.");
        }
    }
};

window.codePush.checkForUpdate(onUpdateCheck, onError);

//------------------------------------------------
// App version 2 (updated version)
var app = {
    onDeviceReady: function () {
        // Calling this function is required during the first application run after an update.
        // If not called, the application will be reverted to the previous version.
        window.codePush.notifyApplicationReady();
        // ...
    }
}

Untuk contoh tentang cara Anda dilindungi dari pembaruan yang buruk, lihat dokumentasi notifyApplicationReady().

RemotePackage

Berisi detail tentang pembaruan yang tersedia untuk diunduh dari server CodePush. Anda mendapatkan referensi ke instans objek ini dengan memanggil codePush.checkForUpdate metode saat pembaruan tersedia. Jika Anda menggunakan API sinkronisasi, Anda tidak perlu khawatir tentang RemotePackage, karena akan menangani proses pengunduhan dan penginstalan secara otomatis untuk Anda.

Properti

Mewarisi RemotePackage semua properti yang sama dengan LocalPackage, tetapi mencakup satu properti tambahan:

  • downloadUrl: URL tempat paket tersedia untuk diunduh. Properti ini hanya diperlukan untuk penggunaan lanjutan, karena download metode akan secara otomatis menangani akuisisi pembaruan untuk Anda. (String)
Metode
  • abortDownload(abortSuccess, abortError): Membatalkan sesi unduhan saat ini, jika ada.
  • download(downloadSuccess, downloadError, downloadProgress): Mengunduh pembaruan paket dari layanan CodePush. Panggilan downloadSuccess balik dipanggil dengan argumen LocalPackage , mewakili paket yang diunduh. Panggilan balik opsional downloadProgress dipanggil beberapa kali selama kemajuan unduhan dengan satu DownloadProgress parameter.
DownloadProgress

Menentukan format objek DownloadProgress, digunakan untuk mengirim pemberitahuan pembaruan berkala tentang kemajuan unduhan pembaruan.

Properti
  • totalBytes: Ukuran paket pembaruan pengunduhan, dalam byte. (Angka)
  • receivedBytes: Jumlah byte yang sudah diunduh. (Angka)

Contoh Penggunaan:

var onError = function (error) {
    console.log("An error occurred. " + error);
};

var onPackageDownloaded = function (localPackage) {
    console.log("Package downloaded at: " + localPackage.localPath);
    // you can now update your application to the downloaded version by calling localPackage.install()
};

var onProgress = function (downloadProgress) {
    console.log("Downloading " + downloadProgress.receivedBytes + " of " + downloadProgress.totalBytes + " bytes.");
};

var onUpdateCheck = function (remotePackage) {
    if (!remotePackage) {
        console.log("The application is up to date.");
    } else {
        console.log("A CodePush update is available. Package hash: " + remotePackage.packageHash);
        remotePackage.download(onPackageDownloaded, onError, onProgress);
    }
};

window.codePush.checkForUpdate(onUpdateCheck, onError);

Enum

CODEPush API mencakup objek "enum" berikut yang dapat digunakan untuk menyesuaikan pengalaman pembaruan, dan tersedia secara global dari window objek:

InstallMode

Enum ini ditentukan ketika Anda ingin pembaruan yang diinstal benar-benar diterapkan, dan dapat diteruskan ke sync metode atau LocalPackage.install . Ini termasuk nilai-nilai berikut:

  • IMMEDIATE: Pembaruan akan segera diterapkan ke aplikasi yang sedang berjalan. Aplikasi akan segera dimuat ulang dengan konten baru.
  • ON_NEXT_RESTART: Menunjukkan bahwa Anda ingin menginstal pembaruan, tetapi tidak menghidupkan ulang aplikasi secara paksa. Ketika aplikasi "secara alami" dimulai ulang (karena OS atau pengguna akhir membunuhnya), pembaruan akan diambil dengan mulus. Nilai ini sesuai ketika melakukan pembaruan senyap, karena kemungkinan akan mengganggu pengguna akhir jika aplikasi tiba-tiba dimulai ulang entah dari mana, karena mereka tidak akan menyadari pembaruan bahkan diunduh. Ini adalah mode default yang digunakan untuk sync metode dan LocalPackage.install .

Untuk contoh tentang cara Anda dilindungi dari pembaruan yang buruk, lihat dokumentasi notifyApplicationReady().

RemotePackage

Berisi detail tentang pembaruan yang tersedia untuk diunduh dari server CodePush. Anda mendapatkan referensi ke instans objek ini dengan memanggil codePush.checkForUpdate metode saat pembaruan tersedia. Jika Anda menggunakan API sinkronisasi, Anda tidak perlu khawatir tentang RemotePackage, karena akan menangani proses pengunduhan dan penginstalan secara otomatis untuk Anda.

Properti

Mewarisi RemotePackage semua properti yang sama dengan LocalPackage, tetapi mencakup satu properti tambahan:

  • downloadUrl: URL tempat paket tersedia untuk diunduh. Properti ini hanya diperlukan untuk penggunaan lanjutan, karena download metode akan secara otomatis menangani akuisisi pembaruan untuk Anda. (String)
Metode
  • abortDownload(abortSuccess, abortError): Membatalkan sesi unduhan saat ini, jika ada.
  • download(downloadSuccess, downloadError, downloadProgress): Mengunduh pembaruan paket dari layanan CodePush. Panggilan downloadSuccess balik dipanggil dengan argumen LocalPackage , mewakili paket yang diunduh. Panggilan balik opsional downloadProgress dipanggil beberapa kali selama kemajuan unduhan dengan satu DownloadProgress parameter.
DownloadProgress

Menentukan format objek DownloadProgress, digunakan untuk mengirim pemberitahuan pembaruan berkala tentang kemajuan unduhan pembaruan.

# Properti
  • totalBytes: Ukuran paket pembaruan pengunduhan, dalam byte. (Angka)
  • receivedBytes: Jumlah byte yang sudah diunduh. (Angka)

Contoh Penggunaan:

var onError = function (error) {
    console.log("An error occurred. " + error);
};

var onPackageDownloaded = function (localPackage) {
    console.log("Package downloaded at: " + localPackage.localPath);
    // you can now update your application to the downloaded version by calling localPackage.install()
};

var onProgress = function (downloadProgress) {
    console.log("Downloading " + downloadProgress.receivedBytes + " of " + downloadProgress.totalBytes + " bytes.");
};

var onUpdateCheck = function (remotePackage) {
    if (!remotePackage) {
        console.log("The application is up to date.");
    } else {
        console.log("A CodePush update is available. Package hash: " + remotePackage.packageHash);
        remotePackage.download(onPackageDownloaded, onError, onProgress);
    }
};

window.codePush.checkForUpdate(onUpdateCheck, onError);

Enum

CODEPush API mencakup objek "enum" berikut yang dapat digunakan untuk menyesuaikan pengalaman pembaruan, dan tersedia secara global dari window objek:

InstallMode

Enum ini ditentukan ketika Anda ingin pembaruan yang diinstal benar-benar diterapkan, dan dapat diteruskan ke sync metode atau LocalPackage.install . Ini termasuk nilai-nilai berikut:

  • IMMEDIATE: Pembaruan akan segera diterapkan ke aplikasi yang sedang berjalan. Aplikasi akan segera dimuat ulang dengan konten baru.
  • ON_NEXT_RESTART: Menunjukkan bahwa Anda ingin menginstal pembaruan, tetapi tidak menghidupkan ulang aplikasi secara paksa. Ketika aplikasi "secara alami" dimulai ulang (karena OS atau pengguna akhir membunuhnya), pembaruan akan diambil dengan mulus. Nilai ini sesuai ketika melakukan pembaruan senyap, karena kemungkinan akan mengganggu pengguna akhir jika aplikasi tiba-tiba dimulai ulang entah dari mana, karena mereka tidak akan menyadari pembaruan bahkan diunduh. Ini adalah mode default yang digunakan untuk sync metode dan LocalPackage.install .
  • ON_NEXT_RESUME: Menunjukkan bahwa Anda ingin menginstal pembaruan, tetapi tidak ingin memulai ulang aplikasi hingga lain kali pengguna akhir melanjutkannya dari latar belakang. Dengan cara ini, Anda tidak mengganggu sesi mereka saat ini, tetapi Anda bisa mendapatkan pembaruan di depannya lebih cepat daripada harus menunggu hidupkan ulang alami berikutnya. Nilai ini sesuai untuk penginstalan senyap yang dapat diterapkan saat dilanjutkan dengan cara non-invasif.

SyncStatus

Menentukan kemungkinan status operasi sinkronisasi . Ada dua kategori status: menengah dan hasil (final). Status perantara mewakili status kemajuan operasi sinkronisasi, dan belum final. Status hasil mewakili status akhir dari operasi sinkronisasi. Setiap operasi sinkronisasi hanya berakhir dengan satu status hasil, tetapi dapat memiliki nol atau lebih status menengah.

  • UP_TO_DATE: Aplikasi ini sepenuhnya diperbarui dengan penyebaran yang dikonfigurasi.
  • UPDATE_INSTALLED: Pembaruan yang tersedia telah diinstal dan akan dijalankan segera setelah fungsi panggilan balik kembali atau lain kali aplikasi dilanjutkan/dimulai ulang, tergantung pada InstallMode yang ditentukan di SyncOptions.
  • UPDATE_IGNORED: Aplikasi ini memiliki pembaruan opsional, yang dipilih pengguna akhir untuk diabaikan. (Ini hanya berlaku ketika updateDialog digunakan)
  • KESALAHAN: Terjadi kesalahan selama sync operasi. Ini mungkin kesalahan saat berkomunikasi dengan server, mengunduh atau membuka zip pembaruan. Log konsol harus berisi informasi lebih lanjut tentang apa yang terjadi. Tidak ada pembaruan yang diterapkan dalam kasus ini.
  • IN_PROGRESS: Sinkronisasi lain sudah berjalan, jadi upaya untuk menyinkronkan ini telah dibatalkan.
  • CHECKING_FOR_UPDATE: Server CodePush sedang dikueri untuk pembaruan.
  • AWAITING_USER_ACTION: Pembaruan tersedia, dan dialog konfirmasi ditampilkan kepada pengguna akhir. (Ini hanya berlaku ketika updateDialog digunakan)
  • DOWNLOADING_PACKAGE: Pembaruan yang tersedia sedang diunduh dari server CodePush.
  • INSTALLING_UPDATE: Pembaruan yang tersedia diunduh dan akan diinstal.

PhoneGap Build

Plugin ini kompatibel dengan PhoneGap Build, dan mendukung pembuatan build Android dan iOS di luar kotak. Namun, agar CodePush menghitung hash konten biner Anda di Android, PhoneGap Build perlu menggunakan Gradle untuk membangun aplikasi Anda, yang bukan perilaku defaultnya (menggunakan Ant). Untuk mengatasinya, tambahkan elemen berikut ke file config.xml proyek, sebagai turunan dari <platform name="android"> elemen :

<preference name="android-build-tool" value="gradle" />

Contoh Aplikasi

Komunitas Cordova telah membuat beberapa aplikasi sumber terbuka mengagumkan yang dapat berfungsi sebagai contoh untuk pengembang yang memulai. Daftar berikut adalah aplikasi OSS Cordova yang juga menggunakan CodePush, dan dapat digunakan untuk melihat bagaimana orang lain menggunakan layanan:

Catatan

Jika Anda telah mengembangkan aplikasi Cordova menggunakan CodePush, itu adalah sumber terbuka, beri tahu kami. Kami ingin menambahkannya ke daftar ini!