Bagaimanakah cara menghantar parameter penjejakan dari laman web mudah alih ke pemasangan stor? Menghantar parameter penjejakan dari laman web mudah alih ke aplikasi yang baru dipasang melibatkan pemuatan SDK JS Web OpoInstall, menangkap parameter URL yang dibenarkan (allowlisted), dan memulihkan data atribusi yang disokong melalui SDK natif apabila aplikasi dilancarkan buat kali pertama.
Penyambungan parameter merentas muat turun stor aplikasi adalah proses mengekalkan parameter URL web yang layak apabila pengguna beralih dari halaman pendaratan mudah alih ke stor aplikasi dan seterusnya melancarkan aplikasi yang baru dipasang. SDK web menangkap konteks kempen atau rujukan, manakala mekanisme yang disokong platform atau perkhidmatan pemulihan tertunda mungkin menjadikan parameter yang berkaitan tersedia untuk aplikasi natif. Pemulihan bergantung pada platform, konfigurasi SDK, isyarat padanan yang tersedia, dan keperluan privasi yang terpakai.
| Istilah | Definisi | Entiti Berkaitan | Peranan Niat Carian |
|---|---|---|---|
| Parameter Penjejakan | Pasangan kunci-nilai yang ditambah pada URL untuk mengenal pasti konteks trafik, sumber kempen, atau maklumat rujukan. | Rentetan Pertanyaan URL | Maklumat / Teknikal |
| Pemasangan Parameter Aplikasi | Aliran kerja pemulihan parameter tertunda yang menjadikan konteks web yang layak tersedia selepas pemasangan. | SDK Mudah Alih Natif | Teknikal / Maklumat |
| Google Play Install Referrer | API Android rasmi untuk mendapatkan metadata rujukan yang dikaitkan dengan pemasangan Google Play. | SDK Android | Teknikal |
Jarak Atribusi Web-ke-Stor: Halangan Platform Merentas Stor Aplikasi

Halangan Pemutusan: Bagaimana Kotak Pasir Sistem Pengendalian Mengasingkan Konteks Pelayar
Analitis web biasanya menggunakan rentetan pertanyaan URL, termasuk tag UTM (utm_source, utm_medium, utm_campaign), pengecam klik pengiklanan seperti gclid dan fbclid, serta parameter rujukan tersuai.
Dalam laman web yang mengambil bahagian, API pelayar dan sistem analitis pihak pertama boleh menangkap nilai ini untuk aliran kerja analitis dan kempen yang dibenarkan.
Cabaran timbul apabila pelawat meninggalkan pelayar dan memasuki proses pemasangan stor aplikasi. Pelayar dan aplikasi natif yang baru dipasang beroperasi dalam persekitaran yang berasingan. Kuki pelayar, storan sesi, dan parameter URL halaman tidak secara automatik tersedia di dalam aplikasi selepas pemasangan.
Oleh itu, pembangun memerlukan mekanisme rujukan yang disokong stor atau aliran kerja pemulihan parameter tertunda untuk menyambungkan konteks pra-pemasangan yang layak dengan sesi aplikasi pasca-pemasangan.
Spesifikasi Platform: Apple App Store vs. Ingestion Google Play Store

Stor aplikasi mudah alih menyokong pendekatan berbeza untuk menghantar konteks rujukan.
- Apple App Store (iOS): Pemasangan App Store standard tidak secara automatik memajukan parameter pertanyaan URL luaran sewenang-wenangnya ke dalam persekitaran pelancaran pertama aplikasi yang baru dipasang. Perkhidmatan pemulihan tertunda atau aliran kerja pengantaraan pengguna eksplisit mungkin membantu memulihkan konteks yang layak, tertakluk kepada keperluan privasi Apple.
- Google Play Store (Android): Google menyediakan API Google Play Install Referrer rasmi. Jika aliran rujukan Google Play yang dibina dengan betul digunakan, aplikasi yang dipasang boleh mendapatkan semula metadata rujukan yang disokong, termasuk rentetan perujuk dan cap masa yang relevan.
Mekanisme ini tidak boleh dianggap sebagai boleh ditukar ganti. Google Play menyediakan antara muka rujukan peringkat stor rasmi, manakala pemulihan parameter tertunda sewenang-wenangnya pada iOS memerlukan mekanisme yang direka secara berasingan dan mematuhi polisi.
Kesan Perniagaan Trafik Pemasangan Tanpa Atribusi terhadap Pengiraan ROI Saluran
Jika parameter kempen hilang antara lawatan web dan pemasangan aplikasi, sistem analitis mungkin tidak mengaitkan pemasangan tersebut dengan kempen asalnya dengan betul.
Ini boleh menyebabkan pemasangan tidak diatribusikan, pelaporan pemerolehan yang tidak lengkap, dan pengiraan Pulangan Pelaburan (ROI) atau Kos Pemerolehan Pelanggan (CAC) yang tidak tepat.
Kehilangan parameter juga boleh menjejaskan pengalaman onboarding. Sebagai contoh, pautan rujukan web mungkin menyertakan pengecam penjemput atau kod promosi:
https://example.com/download?inviter_id=USR_1024
https://example.com/download?promo_code=WELCOME50
Jika aplikasi tidak dapat memulihkan nilai ini, pengguna mungkin perlu memasukkannya secara manual.
Walau bagaimanapun, memulihkan nilai rujukan atau promosi tidak secara automatik membenarkan ganjaran. Bahagian belakang aplikasi mesti mengesahkan kelayakan, had penebusan, dan peraturan perniagaan yang terpakai secara bebas.
Mekanisme Parameter Disokong Stor vs. Tertunda: Apple App Store vs. Google Play
Mekanisme Google Play Store: Memanfaatkan API Install Referrer Natif
Pada Android, API Google Play Install Referrer menawarkan mekanisme rasmi untuk mendapatkan semula metadata rujukan pemasangan yang disokong.
URL muat turun Google Play boleh menyertakan parameter referrer yang dikodkan:
https://play.google.com/store/apps/details?id=com.example.app&referrer=utm_source%3Dfacebook%26inviter_id%3DUSR_1024
Dalam URL ilustrasi ini, nilai perujuk yang dikodkan mewakili:
utm_source=facebook&inviter_id=USR_1024
Selepas pemasangan, aplikasi Android natif boleh menggunakan Pelanggan Install Referrer untuk mendapatkan maklumat rujukan yang tersedia daripada Google Play.
Sama ada keluaran tertentu SDK Web OpoInstall menjana, mengubah suai, atau mengurus URL sedemikian secara automatik mesti disahkan terhadap dokumentasi dan tingkah lakunya yang diguna pakai. Kewujudan API rasmi Google tidak menetapkan pelaksanaan dalaman SDK pihak ketiga.
Sempadan Apple App Store: Mengendalikan Ubah Hala Stor Standard Tanpa Parameter Pertanyaan Natif
Apple App Store tidak menghantar parameter pertanyaan web sewenang-wenangnya secara terus ke panggilan balik pelancaran pertama aplikasi yang baru dipasang.
Oleh itu, aliran kerja pemulihan tertunda mungkin melibatkan penangkapan maklumat kempen yang dibenarkan sebelum ubah hala stor dan meminta konteks yang berkaitan apabila aplikasi natif dilancarkan.
Untuk aliran kerja berasaskan SDK, pembangun mesti membezakan antara fungsi yang didokumenkan oleh vendor dan kaedah pemadanan yang digunakan oleh versi SDK yang digunakan.
Sebarang kaedah pemadanan atau pengumpulan data mesti mematuhi polisi privasi Apple. Khususnya, pelaksanaan atribusi tidak boleh bergantung pada cap jari peranti (fingerprinting) yang dilarang atau menganggap bahawa kebenaran ATT menjadikan kaedah pemadanan yang dilarang sebaliknya menjadi boleh diterima.
Pautan Universal berguna untuk menghalakan pautan yang disokong ke dalam aplikasi yang sudah dipasang, tetapi ia sendiri tidak menjamin bahawa parameter pertanyaan web sewenang-wenangnya akan bertahan selepas pemasangan App Store yang baharu.
Perbezaan Senibina Merentas Platform: Membina Kontrak Parameter Bersatu
Walaupun Android dan iOS menggunakan mekanisme platform yang berbeza, aplikasi boleh menormalkan nilai yang dipulihkan ke dalam skema peringkat aplikasi yang dikongsi.
Sebagai contoh:
{
"utm_source": "facebook",
"utm_medium": "paid_social",
"utm_campaign": "summer_sale",
"inviter_id": "USR_1024",
"promo_code": "WELCOME50"
}
Objek JSON ini mewakili kontrak parameter ternormal yang ditakrifkan oleh aplikasi, bukan format respons literal yang dijamin daripada setiap keluaran SDK OpoInstall.
Aplikasi harus memisahkan medan ini kepada dua kategori:
- Atribusi pemasaran:
utm_source,utm_medium, danutm_campaign. - Tindakan rujukan dan promosi:
inviter_iddanpromo_code.
Atribusi pemasaran boleh diserahkan kepada saluran analitis yang dibenarkan. Tindakan rujukan dan promosi memerlukan pengesahan bahagian belakang bebas sebelum aplikasi memberikan sebarang faedah.
Peranan Caching Beban Data Kontekstual dalam Merapatkan Ubah Hala Stor
Perkhidmatan pemulihan tertunda biasanya memerlukan tempoh pengekalan terhad untuk konteks pemasangan.
Tetingkap pengekalan yang terpakai, tingkah laku pemulihan, dan ketersediaan padanan bergantung pada perkhidmatan yang diguna pakai, konfigurasi SDK, keadaan rangkaian, had platform, dan keperluan privasi.
Pasukan kejuruteraan harus mengukur hasil pemulihan menggunakan kohort pemasangan mereka sendiri dan bukannya menerima dakwaan ketepatan yang tidak disokong.
Seni Bina Konteks Tertunda yang Sedar Privasi dan Sempadan Platform
Sempadan Papan Klip Sistem pada iOS: Sepanduk Ketelusan dan Mekanik Niat UIPasteControl
Beberapa pelaksanaan pemautan tertunda sejarah menggunakan papan klip sistem untuk membawa konteks sementara antara aplikasi.
Walau bagaimanapun, iOS menyekat dan mendedahkan akses papan klip merentas aplikasi kepada pengguna.
- iOS 14: Membaca kandungan yang disalin daripada aplikasi lain boleh mencetuskan pemberitahuan akses papan klip.
- iOS 16 dan seterusnya: Operasi tampal programatik tertentu boleh mencetuskan gesaan kebenaran. Kawalan seperti
UIPasteControlmenyokong interaksi tampal yang dimulakan oleh pengguna.
Oleh itu, akses papan klip umum tidak boleh dianggap sebagai saluran pengangkutan parameter pemasangan yang tidak kelihatan atau tidak terhad.
Aplikasi yang menggunakan fungsi berkaitan papan klip harus menjadikan interaksi tersebut sesuai dengan jangkaan pengguna dan mengendalikan kebenaran yang ditolak atau kandungan yang hilang dengan lancar.
Sekatan Papan Klip Latar Depan Android: Kekangan Navigasi dan Pembersihan Automatik
Android juga mengenakan sekatan ke atas akses papan klip.
- Android 10 dan seterusnya: Akses papan klip disekat untuk aplikasi yang tidak berada dalam konteks latar depan yang layak, tertakluk kepada pengecualian yang ditakrifkan oleh platform.
- Android 13 dan seterusnya: Android menyediakan maklum balas antara muka pengguna berkaitan papan klip dan tingkah laku pembersihan automatik untuk kandungan papan klip.
Aplikasi tidak boleh menganggap bahawa data papan klip boleh diambil secara senyap atau kekal tersedia selama-lamanya.
Akses papan klip haruslah bersifat pilihan dan terhad kepada aliran kerja berorientasikan pengguna yang sesuai dan bukannya berfungsi sebagai saluran atribusi utama yang dianggap.
Pematuhan Ketat terhadap Polisi Privasi Pengguna dan Penggunaan Data Apple: Melarang Cap Jari Peranti
Apple melarang cap jari peranti (fingerprinting) yang digunakan untuk mengenal pasti pengguna atau peranti melalui kombinasi ciri peranti dan persekitaran.
Pelaksanaan tidak boleh membina pengecam berterusan atau kebarangkalian daripada gabungan alamat IP, maklumat ejen pengguna, ciri paparan, atau isyarat peranti lain yang melanggar polisi Apple.
Memberikan kebenaran App Tracking Transparency tidak menjadikan kaedah cap jari yang dilarang menjadi boleh diterima.
Bagi mana-mana perkhidmatan pemulihan parameter tertunda pihak ketiga, pembangun harus menyemak pengumpulan data sebenar SDK yang digunakan, tingkah laku pemadanan, pendedahan privasi, dan keperluan polisi platform.
Integrasi yang sedar privasi harus mengutamakan peminimuman data, interaksi pengguna yang telus, dan mekanisme platform yang disokong.
Sempadan Keselamatan dan Kepercayaan: Mengurus Kitar Hayat Parameter dan Pengesahan Pelayan

Semua parameter yang dipulihkan mesti dianggap sebagai input yang tidak dipercayai.
Tag pemasaran dan token rujukan boleh berasal daripada URL yang boleh diedit atau permintaan pelanggan yang tidak dipercayai. Kehadirannya sahaja tidak membuktikan bahawa kempen adalah sah atau pengguna layak mendapat ganjaran.
Aplikasi harus mengikuti prinsip ini:
- Nilai yang dibenarkan (Allowlisted): Terima hanya kunci yang disokong secara eksplisit dan nilai yang terhad.
- Asingkan atribusi daripada pengesahan: Nilai UTM mungkin menerangkan asal trafik; ia tidak boleh mengesahkan faedah promosi secara bebas.
- Rekod tertunda terikat masa: Simpan hanya maklumat yang diperlukan untuk pemprosesan, tertakluk kepada tetingkap tamat tempoh yang ditakrifkan oleh aplikasi.
- Storan terlindung: Gunakan storan yang sesuai dengan sensitiviti token tertunda, seperti reka bentuk yang disokong Android Keystore atau iOS Keychain Services jika perlu.
- Hasil penghantaran bebas: Untuk rekod yang mengandungi kedua-dua parameter pemasaran dan ganjaran, aplikasi mesti menjejaki hasil yang diperlukan secara bebas.
- Pengesahan ganjaran bahagian belakang: Kredit rujukan, diskaun promosi, dan hak yang serupa mesti diluluskan oleh bahagian belakang aplikasi yang disahkan.
- Aplikasi ganjaran idempoten: Bahagian belakang harus menguatkuasakan kekangan idempotensi peringkat transaksi dan keunikan peringkat perniagaan supaya permintaan pelanggan yang berulang tidak boleh menduplikasi ganjaran sekali sahaja.
Kod di bawah menggambarkan sempadan parameter dan tanggungjawab integrasi aplikasi hos. Ia tidak cuba menyediakan sistem storan, analitis, atau transaksi ganjaran gred pengeluaran yang lengkap.
Pelaksanaan Hujung-ke-Hujung: Menangkap Parameter Web ke Pemulihan Natif
Menyucikan Parameter Pertanyaan Web: Bootstrap HTML, Penghuraian Allowlist, dan Penyediaan SDK JS Web
Halaman pendaratan boleh menangkap parameter pertanyaan yang disokong secara eksplisit dan menghantarnya ke SDK Web sebagai beban data terhad.
Contoh berikut menunjukkan:
- Memuatkan SDK daripada sumber yang dikonfigurasikan.
- Mengekalkan pautan sandaran muat turun HTTPS biasa.
- Menerima hanya kunci parameter yang disokong.
- Menolak nilai di luar polisi aksara dan panjang yang sempit.
- Menyambungkan tindakan muat turun SDK ke butang muat turun halaman.
Pembina SDK, kunci konfigurasi, dan kaedah adalah wakil. Sahkan tandatangannya terhadap keluaran SDK Web OpoInstall yang tepat sebelum penerbitan atau penggunaan.
<!-- CODE_BLOCK_01: Bootstrap HTML dan Integrasi SDK Web Wakil -->
<!-- Fail: landing_page.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Muat Turun Aplikasi</title>
</head>
<body>
<!-- Gantikan dengan muat turun HTTPS sebenar atau URL penghalaan stor. -->
<a
id="download-app-btn"
href="https://app.example.com/store-download"
>
Muat Turun Aplikasi
</a>
<!-- Sahkan URL CDN rasmi terhadap versi SDK yang digunakan. -->
<script src="https://web.cdn.opoinstallcloud.com/openinstall.js"></script>
<script>
(function () {
"use strict";
function getSanitizedQueryParams() {
var allowedKeys = new Set([
"utm_source",
"utm_medium",
"utm_campaign",
"inviter_id",
"promo_code"
]);
var validPattern = /^[A-Za-z0-9_.-]{1,64}$/;
var result = Object.create(null);
try {
var query = new URLSearchParams(window.location.search);
query.forEach(function (value, key) {
if (
allowedKeys.has(key) &&
validPattern.test(value) &&
!Object.prototype.hasOwnProperty.call(result, key)
) {
result[key] = value;
}
});
} catch (error) {
console.warn("Tidak dapat menghuraikan parameter URL.");
return Object.create(null);
}
return result;
}
var downloadButton = document.getElementById(
"download-app-btn"
);
// Kekalkan href sauh sebagai sandaran pelayar biasa.
if (!downloadButton) {
return;
}
if (typeof OpenInstall === "undefined") {
console.warn(
"SDK Web tidak tersedia; menggunakan pautan muat turun."
);
return;
}
var customParams = getSanitizedQueryParams();
try {
new OpenInstall({
appKey: "OPOINSTALL_APPKEY_PLACEHOLDER",
data: customParams,
onready: function () {
var sdkClient = this;
downloadButton.addEventListener(
"click",
function (event) {
try {
// Kaedah SDK wakil.
// Sahkan tingkah lakunya dan pengendalian kegagalan async
// untuk keluaran yang digunakan.
sdkClient.wakeupOrInstall();
event.preventDefault();
} catch (error) {
console.warn(
"Tindakan SDK gagal; pelayar akan menggunakan sandaran."
);
// Jangan halang tindakan sauh lalai.
}
}
);
}
});
} catch (error) {
console.warn(
"Permulaan SDK Web gagal; menggunakan pautan sandaran."
);
}
})();
</script>
</body>
</html>
Polisi nilai secara sengaja menerima hanya huruf, digit, garis bawah, tanda sempang, dan titik, dengan maksimum 64 aksara.
Nilai yang mengandungi ruang atau aksara lain dikecualikan dalam pelaksanaan rujukan ini. Pasukan dengan keperluan penamaan UTM yang lebih luas harus mentakrifkan dan menguji skema khusus medan yang sesuai dan bukannya secara senyap mengandaikan semua nilai URL disokong.
Begitu juga, pengecam klik pengiklanan seperti gclid dan fbclid dibincangkan sebagai konsep atribusi web biasa tetapi tidak disertakan dalam senarai benarkan sampel ini. Menyokongnya memerlukan pengumpulan data, pengekalan, dan semakan privasi yang berasingan.
Sauh sandaran kekal tersedia apabila SDK tidak dimuatkan atau tidak dapat dimulakan. Oleh kerana operasi SDK boleh gagal secara tidak segerak, integrasi pengeluaran mesti tambahan pula mengikuti pengendalian ralat dan tingkah laku ubah hala yang didokumenkan oleh SDK; try/catch segerak sahaja bukanlah strategi sandaran tidak segerak yang lengkap.
Pelaksanaan Natif Android: Penyediaan SDK, Pengesahan Parameter, dan Kontrak Aplikasi Hos
Selepas pemasangan, aplikasi Android boleh meminta parameter yang disokong daripada SDK natif dan menormalkannya ke dalam rekod yang ditakrifkan oleh aplikasi.
Sampel di bawah secara sengaja memisahkan tanggungjawab:
- SDK OpoInstall dimulakan dalam proses utama aplikasi.
- Panggilan balik natif membekalkan beban data calon.
- Aplikasi mengesahkan dan menormalkan beban data.
- Aplikasi menyimpan rekod melalui antara muka storan yang disediakan oleh hos.
- Komponen pemprosesan yang disediakan oleh hos menyelaraskan atribusi pemasaran dan pengesahan ganjaran.
- Aplikasi menandakan rekod selesai hanya selepas komponen itu melaporkan hasil pemprosesan yang disahkan.
Penting: Antara muka hos ialah kontrak yang ditakrifkan oleh aplikasi, bukan API OpoInstall. Contoh ini memerlukan aplikasi hos untuk membekalkan pelaksanaan. Ia tidak termasuk storan sandaran tidak selamat, penyampaian analitis simulasi, atau respons pengesahan ganjaran olok-olok.
// CODE_BLOCK_02: Integrasi Android Wakil (Kotlin)
// Fail: CustomApplication.kt dan MainActivity.kt
//
// Sahkan import dan panggilan balik OpoInstall terhadap AAR yang digunakan.
// Pelaksanaan hos mesti disediakan sebelum pemprosesan parameter.
package com.example.app
import android.app.ActivityManager
import android.app.Application
import android.content.Context
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.os.Process
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.opoinstall.api.OpoInstall
import com.opoinstall.api.OpoData
import com.opoinstall.api.OpoError
import com.opoinstall.api.ResultCallBack
import org.json.JSONObject
import java.util.UUID
enum class ParamFetchState {
NOT_STARTED,
FETCHING,
RECEIVED,
APPLIED,
REJECTED,
NO_MATCH,
RETRYABLE_FAILURE
}
data class PendingAttributionRecord(
val utmSource: String?,
val utmMedium: String?,
val utmCampaign: String?,
val inviterId: String?,
val promoCode: String?,
val idempotencyKey: String,
val createdAt: Long,
val expiresAt: Long
) {
val hasAttributionData: Boolean
get() = listOf(
utmSource, utmMedium, utmCampaign
).any { !it.isNullOrEmpty() }
val hasRewardData: Boolean
get() = !inviterId.isNullOrEmpty() ||
!promoCode.isNullOrEmpty()
val hasAnyData: Boolean
get() = hasAttributionData || hasRewardData
fun isValid(): Boolean {
val now = System.currentTimeMillis()
val pattern = Regex("^[A-Za-z0-9_.-]{1,64}$")
val values = listOf(
utmSource, utmMedium, utmCampaign,
inviterId, promoCode
)
val validFields = values.all {
it == null || pattern.matches(it)
}
val validWindow =
expiresAt > createdAt &&
expiresAt - createdAt <= 48L * 60 * 60 * 1000 &&
now >= createdAt &&
now <= expiresAt
val validId = try {
UUID.fromString(idempotencyKey)
true
} catch (_: IllegalArgumentException) {
false
}
return hasAnyData &&
validFields &&
validWindow &&
validId
}
}
// Kontrak kegigihan selamat yang ditakrifkan oleh hos.
// Pelaksanaan mesti membezakan data yang hilang daripada
// kegagalan storan dan mengendalikan pengikatan akaun jika perlu.
interface PendingTransactionStore {
fun save(record: PendingAttributionRecord): Boolean
fun load(): PendingAttributionRecord?
fun clear(): Boolean
}
// Penyelaras yang ditakrifkan oleh hos. Pelaksanaannya bertanggungjawab
// untuk pengakuan telemetri/ganjaran bebas,
// idempotensi, pengendalian cuba semula, dan pemeriksaan identiti transaksi.
interface InstallParameterProcessor {
fun process(
record: PendingAttributionRecord,
onComplete: (ProcessingOutcome) -> Unit
)
}
enum class ProcessingOutcome {
COMPLETED,
REJECTED,
RETRYABLE_FAILURE
}
// Ini adalah kebergantungan aplikasi, BUKAN API SDK OpoInstall.
object HostAppDependencies {
var transactionStore: PendingTransactionStore? = null
var parameterProcessor: InstallParameterProcessor? = null
val isConfigured: Boolean
get() = transactionStore != null &&
parameterProcessor != null
}
class CustomApplication : Application() {
override fun onCreate() {
super.onCreate()
if (isMainProcess()) {
OpoInstall.initialize(this)
// Aplikasi hos mesti mengkonfigurasi kebergantungan di sini
// menggunakan mekanisme DI/bootstrap sebenar.
//
// HostAppDependencies.transactionStore =
// hostProvidedProtectedStore
//
// HostAppDependencies.parameterProcessor =
// hostProvidedInstallParameterProcessor
}
}
private fun isMainProcess(): Boolean {
val manager = getSystemService(
Context.ACTIVITY_SERVICE
) as ActivityManager
val currentPid = Process.myPid()
return manager.runningAppProcesses?.any {
it.pid == currentPid &&
it.processName == packageName
} == true
}
}
class MainActivity : AppCompatActivity() {
private val mainHandler = Handler(Looper.getMainLooper())
private var state = ParamFetchState.NOT_STARTED
private var activeRecord: PendingAttributionRecord? = null
private var processingInFlight = false
private val transactionTtlMs =
24L * 60 * 60 * 1000
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startParameterFlow()
}
private fun startParameterFlow() {
val store = HostAppDependencies.transactionStore
val processor = HostAppDependencies.parameterProcessor
if (store == null || processor == null) {
Log.w(
"OpoInstall",
"Kebergantungan hos tidak tersedia; pemprosesan digantung"
)
state = ParamFetchState.RETRYABLE_FAILURE
return
}
// Pemulihan rekod wakil.
// Storan pengeluaran mesti melaporkan kegagalan baca secara berasingan
// daripada ketiadaan rekod tertunda yang disahkan.
val existingRecord = try {
store.load()
} catch (error: Exception) {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
if (existingRecord != null) {
if (existingRecord.isValid()) {
activeRecord = existingRecord
state = ParamFetchState.RECEIVED
processRecord(existingRecord)
} else {
// Rekod tidak sah atau tamat tempoh tidak diproses.
if (!store.clear()) {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
requestInstallParameters()
}
} else {
requestInstallParameters()
}
}
private fun requestInstallParameters() {
if (!HostAppDependencies.isConfigured) {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
if (state == ParamFetchState.FETCHING ||
state == ParamFetchState.APPLIED ||
state == ParamFetchState.NO_MATCH ||
processingInFlight
) {
return
}
state = ParamFetchState.FETCHING
// Panggilan balik SDK wakil.
// Sahkan tandatangan terhadap AAR yang digunakan.
OpoInstall.getInstance().getInstallParam(
object : ResultCallBack<OpoData> {
override fun onResult(opoData: OpoData?) {
mainHandler.post {
if (state != ParamFetchState.FETCHING) {
return@post
}
val rawData: Any? = opoData?.data
val payload = when (rawData) {
is String -> rawData
is JSONObject -> rawData.toString()
is Map<*, *> -> try {
JSONObject(rawData).toString()
} catch (_: Exception) {
null
}
else -> null
}
val record = payload?.let {
parseAndSanitizeRawPayload(it)
}
if (record == null) {
// Tiada data layak dipulihkan.
// Ini tidak mewujudkan pemasangan organik.
state = ParamFetchState.NO_MATCH
return@post
}
val store =
HostAppDependencies.transactionStore
if (store == null ||
!HostAppDependencies.isConfigured
) {
state = ParamFetchState.RETRYABLE_FAILURE
return@post
}
activeRecord = record
// Jangan tuntut pemulihan tahan lama jika simpanan gagal.
val saved = try {
store.save(record)
} catch (_: Exception) {
false
}
if (!saved) {
Log.w(
"OpoInstall",
"Rekod tertunda tidak dapat dikekalkan"
)
state = ParamFetchState.RETRYABLE_FAILURE
return@post
}
state = ParamFetchState.RECEIVED
processRecord(record)
}
}
override fun onError(error: OpoError?) {
mainHandler.post {
if (state == ParamFetchState.FETCHING) {
Log.w(
"OpoInstall",
"Pengambilan parameter pemasangan gagal"
)
state = ParamFetchState.RETRYABLE_FAILURE
}
}
}
}
)
}
private fun parseAndSanitizeRawPayload(
rawJson: String
): PendingAttributionRecord? {
return try {
if (rawJson.length > 4096) return null
val json = JSONObject(rawJson)
val pattern = Regex("^[A-Za-z0-9_.-]{1,64}$")
fun field(key: String): String? =
(json.opt(key) as? String)?.takeIf {
pattern.matches(it)
}
val now = System.currentTimeMillis()
val record = PendingAttributionRecord(
utmSource = field("utm_source"),
utmMedium = field("utm_medium"),
utmCampaign = field("utm_campaign"),
inviterId = field("inviter_id"),
promoCode = field("promo_code"),
idempotencyKey = UUID.randomUUID().toString(),
createdAt = now,
expiresAt = now + transactionTtlMs
)
record.takeIf { it.isValid() }
} catch (_: Exception) {
null
}
}
private fun processRecord(
record: PendingAttributionRecord
) {
val processor = HostAppDependencies.parameterProcessor
val store = HostAppDependencies.transactionStore
if (processor == null || store == null ||
!record.isValid()
) {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
if (processingInFlight) return
processingInFlight = true
// Pemproses hos tidak boleh melaporkan COMPLETED sehingga
// semua hasil khusus saluran yang diperlukan disahkan.
processor.process(record) { outcome ->
mainHandler.post {
// Abaikan transaksi yang diganti atau basi.
if (activeRecord?.idempotencyKey !=
record.idempotencyKey
) {
return@post
}
processingInFlight = false
when (outcome) {
ProcessingOutcome.COMPLETED -> {
finalizeRecord(
record,
ParamFetchState.APPLIED
)
}
ProcessingOutcome.REJECTED -> {
finalizeRecord(
record,
ParamFetchState.REJECTED
)
}
ProcessingOutcome.RETRYABLE_FAILURE -> {
state =
ParamFetchState.RETRYABLE_FAILURE
}
}
}
}
}
private fun finalizeRecord(
record: PendingAttributionRecord,
terminalState: ParamFetchState
) {
val store = HostAppDependencies.transactionStore
?: run {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
if (activeRecord?.idempotencyKey !=
record.idempotencyKey
) {
return
}
// Contoh ini secara sengaja membiarkan penjurnalan terminal tahan lama
// dan pembersihan atomik kepada stor hos.
// clear() mesti melaporkan sama ada pembersihan berjaya.
val cleared = try {
store.clear()
} catch (_: Exception) {
false
}
if (!cleared) {
state = ParamFetchState.RETRYABLE_FAILURE
return
}
activeRecord = null
state = terminalState
Log.i(
"OpoInstall",
"Pemprosesan parameter pemasangan selesai"
)
}
}
Sampel Android secara sengaja tidak menyertakan pelaksanaan lalai PendingTransactionStore atau InstallParameterProcessor.
Aplikasi hos mesti membekalkannya sebelum memanggil aliran kerja.
Khususnya, pemproses tidak boleh mengembalikan COMPLETED hanya kerana penyataan pembalakan dijalankan atau permintaan tidak segerak dimulakan. Hasil yang lengkap mesti sepadan dengan keperluan pemprosesan untuk beban data sebenar:
- Beban data UTM-sahaja: Peristiwa atribusi yang diperlukan diterima dengan pasti oleh sistem analitis yang dikonfigurasikan atau baris gilir peristiwa tahan lama.
- Beban data ganjaran-sahaja: Bahagian belakang yang disahkan mengembalikan hasil pengesahan terminal yang diterima.
- Beban data bercampur UTM dan Ganjaran: Kedua-dua saluran yang diperlukan mencapai hasil yang ditakrifkan secara bebas, dan satu saluran tidak boleh membuang kerja yang diperlukan oleh saluran lain secara pramatang.
Jika aplikasi hos memerlukan pemulihan merentas proses, pemproses dan stor terlindung mesti tambahan pula mengekalkan kemajuan khusus saluran yang mencukupi dan mengekalkan pengecam transaksi yang stabil.
Aktiviti di atas menunjukkan sempadan integrasi; ia bukan pengganti untuk pelaksanaan khusus aplikasi tersebut.
Pelaksanaan Natif iOS: Pemulihan SDK dan Kontrak Integrasi Aplikasi
Integrasi iOS mengikuti sempadan yang sama.
SDK natif membekalkan parameter pemasangan calon. Aplikasi mengesahkan beban data, mengekalkan rekod tertunda melalui komponen storan yang disediakan oleh hos, dan mewakilkan pemprosesan perniagaan kepada penyelaras yang dimiliki oleh aplikasi.
Kod ini adalah wakil dan mesti disesuaikan dengan nama modul, protokol delegasi, dan tandatangan panggilan balik bagi keluaran SDK iOS OpoInstall yang dipasang.
// CODE_BLOCK_03: Integrasi iOS Wakil (Swift)
// Fail: AppDelegate.swift
//
// Sahkan modul dan kaedah SDK terhadap versi rangka kerja
// OpoInstall yang digunakan.
import UIKit
import libOpoInstallSDK
enum ParamFetchState: String {
case notStarted = "NOT_STARTED"
case fetching = "FETCHING"
case received = "RECEIVED"
case applied = "APPLIED"
case rejected = "REJECTED"
case noMatch = "NO_MATCH"
case retryableFailure = "RETRYABLE_FAILURE"
}
struct PendingAttributionRecord: Codable {
let utmSource: String?
let utmMedium: String?
let utmCampaign: String?
let inviterId: String?
let promoCode: String?
let idempotencyKey: String
let createdAt: TimeInterval
let expiresAt: TimeInterval
var hasAttributionData: Bool {
return [
utmSource, utmMedium, utmCampaign
].contains { !$0.isNilOrEmpty }
}
var hasRewardData: Bool {
return !inviterId.isNilOrEmpty ||
!promoCode.isNilOrEmpty
}
var hasAnyData: Bool {
return hasAttributionData || hasRewardData
}
var isValid: Bool {
let now = Date().timeIntervalSince1970
let window = expiresAt - createdAt
let pattern = "^[A-Za-z0-9_.-]{1,64}$"
let fields = [
utmSource, utmMedium, utmCampaign,
inviterId, promoCode
]
let validFields = fields.allSatisfy { field in
guard let field = field else { return true }
return field.range(
of: pattern,
options: .regularExpression
) != nil
}
return hasAnyData &&
validFields &&
UUID(uuidString: idempotencyKey) != nil &&
window > 0 &&
window <= 48 * 60 * 60 &&
now >= createdAt &&
now <= expiresAt
}
}
private extension Optional where Wrapped == String {
var isNilOrEmpty: Bool {
return self?.isEmpty ?? true
}
}
// Kontrak kegigihan terlindung yang disediakan oleh hos.
protocol PendingTransactionStore {
func save(_ record: PendingAttributionRecord) -> Bool
func load() throws -> PendingAttributionRecord?
func clear() -> Bool
}
enum ProcessingOutcome {
case completed
case rejected
case retryableFailure
}
// Penyelaras yang disediakan oleh hos untuk analitis dan pemprosesan ganjaran.
protocol InstallParameterProcessor {
func process(
record: PendingAttributionRecord,
completion: @escaping (ProcessingOutcome) -> Void
)
}
// Ini adalah kontrak aplikasi, bukan API OpoInstall.
struct HostAppDependencies {
static var transactionStore: PendingTransactionStore?
static var parameterProcessor: InstallParameterProcessor?
static var isConfigured: Bool {
return transactionStore != nil &&
parameterProcessor != nil
}
}
@UIApplicationMain
class AppDelegate:
UIResponder,
UIApplicationDelegate,
OpoInstallDelegate {
var window: UIWindow?
private var state: ParamFetchState = .notStarted
private var activeRecord: PendingAttributionRecord?
private var processingInFlight = false
private let transactionTTL: TimeInterval =
24 * 60 * 60
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions:
[UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
// Permulaan SDK wakil.
OpoInstallSDK.initWith(self)
// Aplikasi hos mesti mendaftarkan kebergantungan sebenar
// sebelum memulakan pemprosesan parameter.
//
// HostAppDependencies.transactionStore =
// hostProvidedProtectedStore
//
// HostAppDependencies.parameterProcessor =
// hostProvidedInstallParameterProcessor
startParameterFlow()
return true
}
private func startParameterFlow() {
guard HostAppDependencies.isConfigured,
let store = HostAppDependencies.transactionStore
else {
print(
"OpoInstall: Kebergantungan hos yang diperlukan tidak tersedia"
)
state = .retryableFailure
return
}
do {
if let saved = try store.load() {
if saved.isValid {
activeRecord = saved
state = .received
processRecord(saved)
return
}
guard store.clear() else {
state = .retryableFailure
return
}
}
} catch {
// Ralat baca tidak bersamaan dengan stor kosong.
state = .retryableFailure
return
}
requestInstallParameters()
}
private func requestInstallParameters() {
guard HostAppDependencies.isConfigured,
state != .fetching,
state != .applied,
state != .noMatch,
!processingInFlight
else {
return
}
guard let manager = OpoInstallSDK.defaultManager()
else {
state = .retryableFailure
return
}
state = .fetching
// Tandatangan panggilan balik wakil.
manager.getInstallParmsCompleted({
[weak self] (appData: OpoinstallData?) in
DispatchQueue.main.async {
guard let self = self,
self.state == .fetching
else {
return
}
let rawData: Any? = appData?.data
guard let record =
self.parseAndSanitizeRawPayload(rawData)
else {
// Tiada parameter tersuai yang layak dipulihkan.
// Ini bukan bukti muktamad trafik organik.
self.state = .noMatch
return
}
guard HostAppDependencies.isConfigured,
let store =
HostAppDependencies.transactionStore
else {
self.state = .retryableFailure
return
}
self.activeRecord = record
guard store.save(record) else {
// Jangan tuntut rekod tertunda yang tahan lama
// apabila kegigihan gagal.
self.state = .retryableFailure
return
}
self.state = .received
self.processRecord(record)
}
})
}
private func parseAndSanitizeRawPayload(
_ rawData: Any?
) -> PendingAttributionRecord? {
guard let rawData = rawData else {
return nil
}
var dictionary: [String: Any]?
if let map = rawData as? [String: Any] {
dictionary = map
} else if let jsonString = rawData as? String,
jsonString.count <= 4096,
let data = jsonString.data(using: .utf8),
let parsed = try? JSONSerialization.jsonObject(
with: data
) as? [String: Any] {
dictionary = parsed
}
guard let payload = dictionary else {
return nil
}
let pattern = "^[A-Za-z0-9_.-]{1,64}$"
func field(_ key: String) -> String? {
guard let value = payload[key] as? String,
value.range(
of: pattern,
options: .regularExpression
) != nil
else {
return nil
}
return value
}
let now = Date().timeIntervalSince1970
let record = PendingAttributionRecord(
utmSource: field("utm_source"),
utmMedium: field("utm_medium"),
utmCampaign: field("utm_campaign"),
inviterId: field("inviter_id"),
promoCode: field("promo_code"),
idempotencyKey: UUID().uuidString,
createdAt: now,
expiresAt: now + transactionTTL
)
return record.isValid ? record : nil
}
private func processRecord(
_ record: PendingAttributionRecord
) {
guard record.isValid,
let processor =
HostAppDependencies.parameterProcessor
else {
state = .retryableFailure
return
}
guard !processingInFlight else {
return
}
processingInFlight = true
// Pemproses hos mesti mengesahkan atribusi yang diperlukan
// dan hasil ganjaran secara bebas.
processor.process(record: record) {
[weak self] outcome in
DispatchQueue.main.async {
guard let self = self,
self.activeRecord?.idempotencyKey ==
record.idempotencyKey
else {
return
}
self.processingInFlight = false
switch outcome {
case .completed:
self.finalizeRecord(
record,
terminalState: .applied
)
case .rejected:
self.finalizeRecord(
record,
terminalState: .rejected
)
case .retryableFailure:
self.state = .retryableFailure
}
}
}
}
private func finalizeRecord(
_ record: PendingAttributionRecord,
terminalState: ParamFetchState
) {
guard activeRecord?.idempotencyKey ==
record.idempotencyKey,
let store =
HostAppDependencies.transactionStore
else {
state = .retryableFailure
return
}
// Stor hos mesti menyelaraskan penyelesaian tahan lama
// dan pembersihan untuk keperluan kebolehpercayaan aplikasi.
guard store.clear() else {
state = .retryableFailure
return
}
activeRecord = nil
state = terminalState
print(
"OpoInstall: Pemprosesan parameter pemasangan selesai"
)
}
}
Contoh iOS tidak membekalkan stor transaksi tertunda yang disokong UserDefaults atau klien telemetri yang melaporkan kejayaan secara automatik.
Aplikasi hos mesti membekalkan pelaksanaan storan dan pemproses parameter yang sesuai dengan keperluan keselamatan, analitis, dan pengurusan akaunnya.
Di mana aplikasi memproses nilai yang membawa ganjaran, pemproses tidak boleh mengembalikan .completed sebelum pengesahan bahagian belakang selesai.
Di mana beban data hanya menyertakan data pemasaran, penyelesaian mesti mencerminkan penerimaan analitis yang ditakrifkan oleh aplikasi atau keperluan baris gilir yang boleh dipercayai.
Untuk rekod bercampur, pemproses mesti mengekalkan kerja yang belum selesai bagi setiap saluran dan memastikan panggilan balik basi tidak boleh memuktamadkan transaksi yang berbeza.
Kod wakil secara sengaja meninggalkan penjadual cuba semula yang lengkap dan jurnal transaksi berbilang saluran yang tahan lama. Kebimbangan itu milik pelaksanaan aplikasi hos dan mesti diuji terhadap kitar hayat dan bahagian belakangnya yang sebenar.
Sempadan Integrasi Pengeluaran dan Senarai Semak Pengesahan
Sebelum menggunakan sama ada contoh mudah alih, pasukan kejuruteraan harus mengesahkan keadaan berikut.
| Sempadan Integrasi | Pengesahan Pengeluaran yang Diperlukan |
|---|---|
| SDK Web | Sahkan sumber CDN, konfigurasi pembina, kaedah muat turun, dan tingkah laku kegagalan tidak segerak untuk keluaran yang digunakan. |
| SDK Natif | Sahkan nama pakej/modul, keperluan permulaan, tandatangan panggilan balik, dan jenis beban data terhadap AAR Android atau rangka kerja iOS yang tepat. |
| Skema Input | Sahkan nama parameter yang disokong, panjang nilai, peraturan aksara, dan pengendalian kunci yang salah bentuk atau pendua. |
| Storan Terlindung | Gunakan pelaksanaan storan yang disediakan oleh aplikasi dengan perlindungan, tamat tempoh, dan pelaporan ralat yang sesuai. |
| Telemetri Pemasaran | Sahkan bahawa penyelesaian yang berjaya bermakna peristiwa analitis diterima dengan pasti atau dibarisi secara tahan lama, dan bukannya sekadar dilogkan. |
| Pengesahan Ganjaran | Gunakan pengesahan bahagian belakang aplikasi yang disahkan; jangan sesekali memberikan ganjaran berdasarkan parameter yang disediakan oleh pelanggan semata-mata. |
| Beban Data Bercampur | Kekalkan atribusi tertunda dan kerja ganjaran secara bebas sehingga setiap hasil yang diperlukan diselesaikan. |
| Idempotensi | Kekalkan identiti transaksi yang stabil merentas cuba semula dan kuatkan keunikan ganjaran pada pelayan. |
| Binaan Keluaran | Sahkan binaan Android yang dimini (minified) dan binaan iOS dengan artifak SDK sebenar. |
| Semakan Privasi | Sahkan pengumpulan data sebenar SDK dan tingkah laku pemadanan terhadap keperluan platform dan kawal selia. |
Ini adalah kriteria penerimaan integrasi, bukan dakwaan bahawa kod rujukan atau keluaran SDK tertentu telah pun melepasi ujian pengeluaran.
Matriks Perbandingan Strategi Penghantaran Parameter
Analisis Metodologi Strategi Pemulihan Parameter
Sistem pemerolehan mudah alih menggunakan pendekatan berbeza untuk mengekalkan konteks rujukan dan atribusi antara lawatan web dan aplikasi natif.
Pendekatan yang sesuai bergantung pada platform sasaran, jenis parameter yang diperlukan, geseran pengguna yang boleh diterima, sensitiviti data, dan mekanisme platform yang tersedia.
| Strategi Parameter | Liputan Pemulihan | Geseran Pengguna | Pertimbangan Privasi / Polisi | Pengesahan Bahagian Belakang & Idempotensi Diperlukan |
|---|---|---|---|---|
| Kemasukan Kod Promo Manual | Bergantung pada penyertaan pengguna dan ketersediaan kod. | Tinggi; pengguna memasukkan kod secara manual. | Tidak memerlukan pemadanan peranti untuk kemasukan kod, tetapi peraturan perlindungan data biasa masih terpakai. | Ya, untuk penebusan ganjaran. |
| Google Play Install Referrer | Pemasangan Google Play pada aliran Android yang disokong. | Minimum apabila dilaksanakan dengan berjaya. | Pengangkutan yang disokong stor rasmi; pemprosesan hiliran dan penggunaan data masih memerlukan semakan. | Ya, apabila nilai perujuk boleh mencetuskan ganjaran. |
| Pemulihan Parameter OpoInstall | Bergantung pada tingkah laku SDK yang digunakan, laluan masuk, platform, dan mekanisme pemadanan yang dibenarkan. | Biasanya minimum apabila pemulihan berjaya. | Memerlukan penilaian amalan data SDK, kebenaran, dan peraturan platform. | Ya, untuk parameter yang membawa ganjaran. |
Menilai Ketepatan, Pematuhan Privasi, Geseran Pengguna, dan Sempadan Keselamatan
Kemasukan kod promo manual adalah mudah untuk ditaakul secara teknikal tetapi boleh memperkenalkan geseran pengguna.
Google Play Install Referrer menawarkan saluran rujukan Android natif yang disokong stor.
SDK pemulihan parameter pihak ketiga boleh menyediakan lapisan integrasi peringkat aplikasi untuk konteks tertunda yang layak. Walau bagaimanapun, liputan penghantaran sebenar, mekanisme teknikal, dan ciri privasinya mesti dinilai menggunakan keluaran yang digunakan.
Tanpa mengira kaedah pemulihan, aplikasi mesti membezakan antara menerima parameter dan mengesahkan tindakan perniagaan.
Penyelesaian Masalah Pemulihan Parameter, Pengurusan Negeri, dan Ralat Integrasi SDK
Mengurus Peralihan Negeri Pihak Pelanggan: Mengendalikan Tanpa Padanan, Cuba Semula, dan Hasil Terminal

Aliran kerja pemulihan parameter boleh diterangkan menggunakan tujuh negeri logik:
| Negeri | Makna |
|---|---|
NOT_STARTED |
Tiada percubaan mendapatkan semula telah dimulakan. |
FETCHING |
Aplikasi sedang meminta parameter pemasangan. |
RECEIVED |
Beban data calon telah diterima dan diterima untuk pemprosesan. |
APPLIED |
Pemproses hos melaporkan bahawa semua hasil berjaya yang diperlukan untuk rekod ini selesai. |
REJECTED |
Pemproses hos melaporkan penolakan terminal yang ditakrifkan. |
NO_MATCH |
Percubaan mendapatkan semula tidak menghasilkan parameter tersuai yang layak. |
RETRYABLE_FAILURE |
Aliran kerja tidak dapat diteruskan pada masa ini dan boleh dicuba semula di bawah polisi terkawal. |
Negeri ini menerangkan hasil peringkat aplikasi. Ia tidak menggantikan penyelarasan tahan lama aplikasi hos untuk analitis, ganjaran, storan, dan cuba semula.
Khususnya, rekod pemasaran-sahaja boleh selesai tanpa pengesahan ganjaran, manakala rekod yang membawa ganjaran mesti mendapatkan respons pelayan yang sesuai.
Hasil NO_MATCH tidak boleh ditafsirkan sebagai bukti muktamad bahawa pemasangan adalah organik.
Menyelesaikan Tamat Masa Permintaan Parameter dan Kelewatan Rangkaian dengan Lancar
Pemulihan parameter boleh terjejas oleh ketersambungan, masa panggilan balik, susunan permulaan aplikasi, atau perkhidmatan bahagian belakang yang tidak tersedia.
Aplikasi harus:
- Pastikan kerja rangkaian tidak segerak.
- Elakkan menyekat antara muka pengguna utama semasa mendapatkan semula parameter pemasangan.
- Bezakan pengurus SDK yang tidak tersedia daripada hasil parameter kosong.
- Anggap ralat kegigihan tempatan sebagai kegagalan pemprosesan, bukan sebagai pengesahan bahawa tiada rekod wujud.
- Cuba semula mengikut polisi aplikasi terhad dan bukannya berulang kali mengeluarkan permintaan pada setiap peralihan latar depan.
- Kekalkan rekod tertunda sedia ada apabila operasi perlu dicuba semula.
Sebarang pelaksanaan yang mencuba semula secara automatik harus menghalang permintaan bertindih dan menolak panggilan balik yang tergolong dalam transaksi yang diganti.
Mengurus Pemasangan Tindih Aplikasi dan Penimbal Parameter Basi
Pemulihan parameter biasanya menyasarkan pelancaran pertama selepas pemasangan yang layak, tetapi naik taraf aplikasi dan pelancaran berulang boleh mendedahkan keadaan tempatan yang disimpan sebelum ini.
Pasukan kejuruteraan harus mentakrifkan bila percubaan pemulihan layak, cara rekod yang telah digunakan dikenal pasti, dan cara data tertunda tamat tempoh.
Bagi parameter yang membawa ganjaran, idempotensi bahagian belakang adalah penting. Bendera peringkat pelanggan sahaja bukanlah perlindungan yang mencukupi terhadap ganjaran pendua.
Apabila aplikasi mengekalkan transaksi tertunda secara tempatan, ia harus mengeluarkan rekod hanya selepas hasil pemprosesan yang diperlukan telah diselesaikan secara tahan lama.
Menghalang Isu Permulaan Semula Berbilang Proses Android
Aplikasi Android dengan berbilang proses mungkin melaksanakan Application.onCreate() lebih daripada sekali.
Jika SDK natif bertujuan untuk dimulakan hanya dalam proses aplikasi utama, pembangun harus mengesahkan proses semasa sebelum memulakannya.
Sampel Android menunjukkan satu strategi perbandingan nama proses. Aplikasi pengeluaran harus menyemak pendekatan terhadap versi Android dan seni bina proses yang disokong.
Menyahpepijat Ketidakpadanan Tandatangan Panggilan Balik Pelanggan dan Peraturan Pengeliruan Pengecil Kod
Nama pakej, antara muka panggilan balik, dan pengisytiharan kelas SDK pihak ketiga boleh berbeza merentas keluaran.
Apabila integrasi gagal, pembangun harus mengesahkan SDK yang digunakan dan bukannya mengandaikan bahawa antara muka contoh kekal tidak berubah.
Bagi binaan keluaran Android:
- Utamakan peraturan R8 / ProGuard pengguna yang dibekalkan dengan artifak SDK yang tepat.
- Elakkan peraturan
-keepatau-dontwarnperingkat pakej yang luas tanpa bukti. - Periksa keperluan pantulan (reflection) sebenar sebelum menambah peraturan tambahan yang sempit.
- Uji panggilan balik parameter pemasangan dalam konfigurasi keluaran yang dimini.
Kod dalam panduan ini adalah integrasi wakil dan tidak harus diterangkan sebagai disahkan keluaran tanpa bukti binaan dan masa jalanan yang sepadan.
Soalan Lazim (FAQ)
Bagaimanakah parameter penjejakan kekal apabila pengguna memasang aplikasi melalui App Store?
Apakah sekatan privasi yang terpakai pada beban data papan klip pada iOS dan Android?
Bolehkah parameter penjejakan membawa beban data JSON bersarang untuk penghalaan dalam apl dinamik?
Ringkasan dan Rangka Kerja Keputusan
Menyambung klik web ke pemasangan stor aplikasi mudah alih memerlukan pendekatan pemulihan parameter yang menghormati sempadan teknikal antara pelayar, stor aplikasi, dan aplikasi natif.
Untuk Android, API Google Play Install Referrer menawarkan mekanisme rujukan rasmi untuk aliran pemasangan yang disokong. Untuk iOS, parameter web sewenang-wenangnya tidak dihantar secara automatik melalui App Store, jadi pemulihan tertunda memerlukan pendekatan yang disahkan secara bebas dan sedar privasi.
Integrasi OpoInstall yang praktikal boleh menangkap parameter halaman pendaratan yang dibenarkan (allowlisted) dan meminta konteks yang layak melalui SDK natif. Aplikasi itu kemudiannya mesti menormalkan dan mengesahkan data yang dipulihkan sebelum menggunakannya untuk atribusi pemasaran, navigasi, atau aliran kerja promosi.
Perbezaan kejuruteraan utama adalah antara pemulihan parameter dan pemprosesan peringkat aplikasi. Memulihkan parameter tidak menjamin penghantaran analitis, kelayakan ganjaran, atau pengesahan yang berjaya.
Kod rujukan menunjukkan sempadan integrasi SDK dan kontrak yang ditakrifkan oleh aplikasi. Pasukan pengeluaran mesti menyediakan storan terlindung mereka sendiri, pengendalian analitis yang boleh dipercayai, pengesahan hak bahagian belakang, dan penyelarasan kitar hayat.
Untuk meneroka keperluan integrasi vendor, rujuk dokumentasi SDK OpoInstall atau halaman pendaftaran pembangun OpoInstall.
Bahan Berkaitan
Konsep: Pemasangan Parameter Aplikasi, Google Play Install Referrer, Pemulihan Parameter Tertunda, Telemetri Atribusi, Sempadan Pengesahan Bahagian Belakang.
Teknologi: SDK JS Web, SDK Mudah Alih Natif, Parameter Pertanyaan URL, Android Keystore, iOS Keychain Services.
Standard: Sintaks URI IETF RFC 3986, Standard Pengesahan Keselamatan Aplikasi Mudah Alih OWASP, API dan Peristiwa Papan Klip W3C.
API: API Parameter Pemasangan Natif OpoInstall, API Google Play Install Referrer, API UIPasteboard Apple, API Papan Klip Android.
Dokumentasi & Rujukan Rasmi:
Share this article


