در دنیای توسعه نرم افزار موبایل، هدایت بی دردسر کاربر از فضای وب، پیامک ها، ایمیل های مارکتینگ و شبکه های اجتماعی به بخش خاصی از اپلیکیشن یکی از حیاتی ترین عوامل افزایش نرخ تبدیل و حفظ مخاطب است. قابلیت دیپ لینک به عنوان پل ارتباطی دنیای وب با محیط محلی سیستم عامل اندروید عمل می کند.
پژوهش های تحلیلی رفتار کاربران نشان می دهد که پیاده سازی اصولی Android App Links نرخ تعامل و فعال سازی درون برنامه ای را تا ۳۸ درصد افزایش داده و نرخ ریزش کاربران در مرحله باز شدن لینک را تا ۶۲ درصد کاهش می دهد. این آمار نشان می دهد که بهینه سازی ناوبری عمیق یکی از پربازده ترین اقدامات فنی در مهندسی محصول است.
با این حال، پیاده سازی نادرست دیپ لینک ها می تواند به تجربه کاربری نامطلوبی منجر شود؛ از جمله باز شدن پنجره مزاحم انتخاب مرورگر (Disambiguation Dialog)، هدایت اشتباه کاربر یا حتی ربوده شدن لینک ها توسط اپلیکیشن های مخرب رقیب. برای حل این چالش ها، شرکت گوگل مکانیزم تایید دامنه موسوم به Android App Links را معرفی کرد.
با ظهور فریمورک Jetpack Compose و معماری ناوبری تک اکتیویتی (Single-Activity Navigation)، مدیریت لینک های عمیق دچار دگرگونی مثبتی شده است. امروزه توسعه دهندگان می توانند الگو های آدرس دهی را به صورت Type-Safe مستقیماً به مقصدهای Composable متصل نمایند. در این راهنمای جامع مهندسی، تمام جنبه های پیاده سازی، اعتبارسنجی سرور و نکات امنیتی را کالبدشکافی می کنیم.
assetlinks.json در سرور HTTPS. لینک های تایید شده بدون نمایش دیالوگ انتخاب اپلیکیشن، کاربر را مستقیماً به صفحه مقصد در Navigation Compose هدایت می کنند.
۱. کالبدشکافی انواع دیپ لینک در اندروید: از Custom Schemes تا Android App Links
سیستم عامل اندروید برای باز کردن پیوندها از مکانیزم Intent های عمومی (Implicit Intents) بهره می برد. وقتی کاربر روی یک پیوند وب لمس می کند، سیستم عامل به جستجوی اپلیکیشن هایی می پردازد که برای دریافت آن نوع داده ثبت نام کرده اند. برای درک تفاوت های ساختاری، باید سه دسته اصلی پیوندها را از یکدیگر تفکیک کنیم:
- دیپ لینک های با اسکیم سفارشی (Custom URI Schemes): پیوندهایی نظیر
myapp://product/120که بسیار ساده پیاده سازی می شوند، اما هیچ تضمینی برای انحصاری بودن آنها وجود ندارد. هر برنامه دیگری می تواند همین اسکیم را در مانیفست خود تعریف کرده و داده های کاربر را برباید. - لینک های وب استاندارد (Web Links): پیوندهایی با پروتکل های استاندارد
httpیاhttpsکه اگر چند برنامه مدعی پشتیبانی از آن باشند، دیالوگ انتخاب برنامه برای کاربر باز می شود تا بین مرورگر یا برنامه های مختلف یکی را برگزیند. - پیوندهای تایید شده برنامه (Android App Links): پیوندهای HTTPS که مالکیت دامنه وب سایت توسط فایل
assetlinks.jsonاثبات شده است. این پیوندها تنها در اپلیکیشن رسمی شما باز می شوند و بیش از ۲ برابر سرعت بارگذاری بالاتری نسبت به مسیرهای سنتی دارند.
از نسخه اندروید ۱۲ به بعد، شرکت گوگل قوانین سخت گیرانه تری وضع کرده است. سیستم عامل دیگر برای وب لینک های عادی دیالوگ انتخاب برنامه را باز نمی کند و به طور پیش فرض آنها را در مرورگر وب نمایش می دهد، مگر آنکه فرآیند تایید App Links با موفقیت طی شده باشد. این تغییر بزرگ، اهمیت یادگیری پیاده سازی اصولی App Links را دوچندان کرده است.
اگر در آغاز مسیر توسعه نرم افزار موبایل هستید و می خواهید ساختار سیستم Intent و چرخه حیات کامپوننت ها را از ریشه یاد بگیرید، پیشنهاد می کنیم راهنمای جامع آموزش برنامه نویسی اندروید را به عنوان نقشه راه استاندارد بررسی فرمایید.
۲. معماری فرآیند اعتبارسنجی App Links و Digital Asset Links
هنگامی که کاربر اپلیکیشنی با قابلیت App Links را نصب می کند، سیستم عامل اندروید به طور خودکار به دامنه وب مشخص شده در مانیفست مراجعه کرده و فایل assetlinks.json را فراخوانی می نماید. این فرآیند بر اساس پروتکل استاندارد Digital Asset Links انجام می پذیرد.
سیستم عامل اثر انگشت رمزنگاری شده کلید انتشار برنامه (SHA-۲۵۶ Fingerprint) را با مقدار درج شده در فایل سرور مقایسه می کند. در صورت تطابق صد در صدی، این دامنه به عنوان دامنه تایید شده (Verified Domain) در تنظیمات سیستمی دستگاه ثبت می گردد. از این لحظه به بعد، کلیک روی هر لینکی از این دامنه، مستقیماً وارد برنامه می شود.
این فرآیند به صورت کاملاً غیرهمگام در پس زمینه انجام می گیرد تا خللی در زمان نصب یا اجرای نخستین برنامه پدید نیاید. اگر سرور وب در زمان نصب پاسخگو نباشد، سیستم عامل در بازه های زمانی بعدی فرآیند بررسی را تکرار خواهد کرد.
برای آشنایی عمیق با اصول پایه فریمورک کامپوز و سیستم رندرینگ صفحات مقصد، مطالعه مقاله تفصیلی آموزش جامع Jetpack Compose به شما توصیه می گردد.
۳. جدول مقایسه فنی: انواع پیوندهای عمیق در مهندسی سیستم های اندروید
برای انتخاب پروتکل ناوبری مناسب در پروژه های تجاری، شناخت دقیق رفتار سیستم عامل در برابر هر یک از شیوه های پیوند الزامی است:
| شاخص ارزیابی فنی | اسکیم سفارشی (Custom Scheme) | وب لینک استاندارد (Web Link) | اندروید اپ لینک (Android App Link) |
|---|---|---|---|
| فرمت آدرس URL | اسکیم های غیروب مانند myapp:// | پروتکل http یا https | صرفاً پروتکل امن https |
| نیاز به تایید دامنه | خیر (فاقد مکانیزم تایید هویت) | خیر | بله (الزامی از طریق assetlinks.json) |
| رفتار در اندروید ۱۲ به بعد | باز شدن دیالوگ یا اجرای مستقیم | هدایت اجباری به مرورگر کروم | باز شدن مستقیم و بلادرنگ در اپلیکیشن |
| امنیت در برابر جعل آدرس | بسیار ضعیف (آسیب پذیر در برابر Phishing) | متوسط | حداکثر (محافظت با امضای کریپتوگرافیک SHA-۲۵۶) |
| رفتار در صورت نصب نبودن اپ | خطای عدم یافتن برنامه (Crash / Error) | باز شدن عادی سایت در مرورگر | هدایت یکپارچه به نسخه وب سایت |
| مناسب برای کمپین های تبلیغاتی | تنها در محیط های بسته داخلی | خیر | بسیار عالی و استاندارد بین المللی |
۴. پیکربندی فایل AndroidManifest.xml برای پشتیبانی از autoVerify
برای اینکه سیستم عامل متوجه شود اپلیکیشن شما قصد تایید خودکار دامنه را دارد، باید فیلترهای Intent مشخصی با ویژگی android:autoVerify="true" درون تگ اکتیویتی مقصد در مانیفست تعریف کنید. این ویژگی فرمان ارسال درخواست اعتبارسنجی را در لحظه نصب به سیستم عامل صادر می کند:
<!-- AndroidManifest.xml -->
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<!-- فیلتر اصلی برای لانچر برنامه -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- فیلتر تایید خودکار App Links برای دامنه رسمی -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="example.com" />
<data android:pathPrefix="/products" />
</intent-filter>
</activity>
وجود تگ android.intent.category.BROWSABLE الزامی است؛ زیرا این دسته بندی به مرورگرها اجازه می دهد تا لینک های باز شده از سوی کاربر را به سمت اپلیکیشن محلی هدایت کنند. در صورت عدم درج این خط، سیستم مرورگر اجازه تحویل اینتنت به اپلیکیشن را صادر نخواهد کرد.
ویژگی android:launchMode="singleTask" مانع از ایجاد نسخه های متعدد از اکتیویتی در صورت کلیک های مکرر کاربر روی لینک ها می گردد و رویدادهای جدید را به متد onNewIntent تحویل می دهد. این رویکرد حافظه دستگاه را حفظ کرده و پایداری برنامه را افزایش می دهد.
۵. ساخت و بارگذاری فایل assetlinks.json روی سرور هاست
سیستم عامل اندروید برای تایید مالکیت دامنه، فایلی با ساختار JSON را در مسیر دقیق زیر درخواست می کند:
https://example.com/.well-known/assetlinks.json
این فایل باید دارای هدر پاسخ Content-Type: application/json باشد، بدون هیچ گونه ریدایرکت (کد وضعیت ۲۰۰ مستقیم) تحویل داده شود و گواهی SSL سرور کاملاً معتبر و بدون هشدار امنیتی باشد. حتی وجود یک ریدایرکت ۳۰۱ از بدون www به با www می تواند کل فرآیند اعتبارسنجی را با شکست مواجه کند.
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example.myapp",
"sha256_cert_fingerprints": [
"14:6D:E9:7F:02:4F:45:4A:87:6B:04:8E:90:5F:8A:22:98:5D:1E:54:15:33:17:89:01:23:45:67:89:AB:CD:EF"
]
}
}]
برای به دست آوردن اثرانگشت SHA-۲۵۶ کلید انتشار برنامه خود، می توانید از دستور استاندارد ابزار Keytool در ترمینال بهره بگیرید:
keytool -list -v -keystore my-release-key.jks -alias my-alias
اگر اپلیکیشن خود را از طریق Google Play App Signing منتشر کرده اید، حتماً اثر انگشت SHA-۲۵۶ موجود در پنل پلی کنسول (قسمت Setup > App Signing) را درون فایل سرور قرار دهید؛ زیرا گوگل فایل باینری را با کلید خود مجدداً امضا می کند.
۶. پیاده سازی دیپ لینک ها در Navigation Compose با متد navDeepLink
در فریمورک Jetpack Compose، ناوبری بر پایه مسیرها (Routes) تعریف می شود. کامپوننت Navigation Compose دارای تابع قدرتمندی به نام navDeepLink است که به شما اجازه می دهد الگو های URL را مستقیماً به مقاصد گرافیکی متصل نمایید.
import androidx.navigation.NavType
import androidx.navigation.compose.composable
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink
val uriPattern = "https://example.com/products/{productId}"
composable(
route = "product_detail/{productId}",
arguments = listOf(
navArgument("productId") { type = NavType.StringType }
),
deepLinks = listOf(
navDeepLink { uriPattern = "https://example.com/products/{productId}" }
)
) { backStackEntry ->
val productId = backStackEntry.arguments?.getString("productId") ?: ""
ProductDetailScreen(productId = productId)
}
اگر لینک شما شامل پارامترهای اختیاری کوئری (Query Parameters) مانند کد تخفیف یا شناسه ارجاع است، می توانید الگوی URL را با علامت سوال تنظیم کنید:
navDeepLink {
uriPattern = "https://example.com/checkout?discountCode={code}"
}
برای تسلط بر ساختار کلی و تفکیک گراف های پیچیده ناوبری، راهنمای تخصصی معماری تمیز در مهندسی نرم افزار را به عنوان زیربنای مهندسی پروژه مطالعه کنید.
۷. ناوبری نوع امن (Type-Safe Navigation) با Kotlin Serialization در Navigation ۲.۸
با انتشار کتابخانه Navigation ۲.۸، شرکت گوگل رویکرد مبتنی بر رشته (String-Based Routes) را منسوخ و مسیردهی کاملاً Type-Safe بر پایه کتابخانه kotlinx.serialization را معرفی کرد. در این متد جدید، مقاصد با کلاس ها و اشیای داده ای تعریف می شوند و خطاهای زمان اجرا به زمان کامپایل منتقل می گردند.
برای پشتیبانی از دیپ لینک در مدل Type-Safe، کافی است آرگومان deepLinks را با الگوی URI و نگاشت مستقیم به کلاس مقصد مقداردهی کنید:
import kotlinx.serialization.Serializable
import androidx.navigation.compose.composable
import androidx.navigation.navDeepLink
@Serializable
data class ProductDetailRoute(val productId: String)
composable<ProductDetailRoute>(
deepLinks = listOf(
navDeepLink<ProductDetailRoute>(
basePath = "https://example.com/products"
)
)
) { backStackEntry ->
// پارامترها به صورت کاملاً خودکار deserialize می شوند
val args = backStackEntry.toRoute<ProductDetailRoute>()
ProductDetailScreen(productId = args.productId)
}
این رویکرد مدرن نیاز به استخراج دستی پارامترها از شیء Bundle و تبدیل رشته ها را به طور کامل از بین می برد و ضریب خطای انسانی در پروژه های مقیاس بزرگ را به صفر می رساند.
۸. قوانین بهینه سازی کدهای R۸ و ProGuard برای مسیرهای دیپ لینک
یکی از شایع ترین دلایل کرش اپلیکیشن پس از انتشار نسخه Release در گوگل پلی، حذف شدن یا تغییر نام فیلدهای کلاس های ناوبری توسط ابزار مینیفایر R8 است. کتابخانه سریال سازی کاتلین نیازمند حفظ نام فیلدها برای انطباق با پارامترهای آدرس اینترنتی است.
برای حل این معضل، قوانین زیر را در فایل proguard-rules.pro پروژه اندروید خود قرار دهید تا اعتبارسنجی پارامترهای URL دچار اختلال نگردد:
# ProGuard Rules for Navigation & Serialization
-keepattributes *Annotation*,Signature,InnerClasses
-dontnote kotlinx.serialization.**
-keepclassmembers class * implements kotlinx.serialization.KSerializer {
static ** Companion;
}
-keepclasseswithmembers class * {
@kotlinx.serialization.Serializable <fields>;
}
با درج این دستورات، ابزار فشرده ساز بدون حذف امضاهای ضروری، حجم نهایی برنامه را بهینه می سازد و مسیرهای دیپ لینک با ثبات صد در صدی اجرا می شوند.
۹. مدیریت چرخه حیات، Intent های جدید و اکتیویتی تک نسخه ای
در معماری تک اکتیویتی، هنگامی که برنامه در پس زمینه در حال اجراست و کاربر روی یک دیپ لینک جدید کلیک می کند، سیستم عامل به طور خودکار متد onNewIntent اکتیویتی را فراخوانی می نماید. اگر این رویداد به درستی به کنترلر ناوبری تحویل داده نشود، صفحه مقصد بارگذاری نخواهد شد.
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.navigation.NavHostController
class MainActivity : ComponentActivity() {
private var navController: NavHostController? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
AppNavGraph(onNavControllerCreated = { navController = it })
}
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
// انتقال اینتنت جدید به کنترلر ناوبری کامپوز
navController?.handleDeepLink(intent)
}
}
تابع navController?.handleDeepLink(intent) وظیفه تحلیل خودکار URL و هدایت بی وقفه کاربر به مقصد جدید را بر عهده دارد، بدون اینکه استک ناوبری قبلی کاربر به شکلی نامنظم تخریب شود.
۱۰. مدیریت لینک های تعلیق شده (Pending Deep Links) و احراز هویت شرطی
یکی از سناریوهای رایج در مهندسی محصول، دریافت دیپ لینک از طریق پوش نوتیفیکیشن یا زمان هایی است که اپلیکیشن هنوز در حال احراز هویت کاربر است. اگر کاربر لاگین نکرده باشد، نباید بلافاصله به صفحه سبد خرید منتقل شود.
الگوی استاندارد برای این سناریو، ذخیره سازی موقت آدرس URL درخواست شده در یک کلاس مدیریت ناوبری یا ریپازیتوری لایه دامنه است. پس از تکمیل فرآیند لاگین، سیستم ناوبری به صورت خودکار کاربر را به صفحه ای که در ابتدا قصد مشاهده آن را داشت منتقل می کند.
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
class DeepLinkRouter {
private val _pendingRoute = MutableStateFlow<String?>(null)
val pendingRoute = _pendingRoute.asStateFlow()
fun savePendingRoute(route: String) {
_pendingRoute.value = route
}
fun consumePendingRoute(): String? {
val target = _pendingRoute.value
_pendingRoute.value = null
return target
}
}
همچنین جهت بررسی تکنیک های ذخیره سازی امن وضعیت ها و توکن های احراز هویت در دیتابیس های محلی، به مقاله آموزش دیتابیس Room در اندروید مراجعه نمایید.
۱۱. مدیریت پشته بازگشت مصنوعی (Synthetic Task Stack) و تجربه کاربری بازگشت
هنگامی که کاربر مستقیماً از طریق یک لینک خارجی وارد صفحه جزئیات محصول می شود، انتظار دارد با فشردن دکمه بازگشت (Back Button) سیستم عامل، به صفحه خانه اپلیکیشن هدایت شود، نه اینکه برنامه فوراً بسته شده و او به صفحه وب قبلی پرتاب شود.
کامپوننت Navigation Compose به صورت پیش فرض یک پشته بازگشت مصنوعی (Synthetic Back Stack) ایجاد می کند. این پشته مقصد شروع گراف ناوبری (معمولاً صفحه خانه یا Home) را به عنوان ریشه استک در نظر می گیرد. بنابراین با زدن دکمه بازگشت، کاربر به صفحه خانه بازمی گردد.
اگر از معماری چند اکتیویتی یا کامپوننت های کلاسیک استفاده می کنید، می توانید این رفتار را با استفاده از ابزار TaskStackBuilder سیستم عامل اندروید پیاده سازی نمایید:
import android.app.PendingIntent
import android.app.TaskStackBuilder
import android.content.Context
import android.content.Intent
fun createDeepLinkPendingIntent(context: Context, intent: Intent): PendingIntent {
return TaskStackBuilder.create(context).run {
addNextIntentWithParentStack(intent)
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
}
}
این ساختار تجربه کاربری روان و پیوسته ای خلق می کند که ماندگاری کاربر در اپلیکیشن را به طور چشمگیری تقویت می نماید.
۱۲. پایش، تحلیل و ردگیری داده های کمپین ها (Deep Link Analytics)
در کمپین های تبلیغاتی دیجیتال مارکتینگ، ردگیری کانال های ورودی کاربران اهمیت زیادی دارد. لینک های تبلیغاتی معمولاً حامل پارامترهای استاندارد UTM مانند utm_source، utm_medium و utm_campaign هستند. بررسی داده های فروش نشان می دهد که تحلیل دقیق این پارامترها نرخ بازگشت سرمایه تبلیغات را تا ۴۵ درصد ارتقا می بخشد.
برای استخراج این پارامترها و ارسال آنها به سرور تحلیل داده بدون مسدود سازی رشته اصلی رابط کاربری، می توان از الگوی زیر در لایه سرویس ناوبری استفاده نمود:
import android.net.Uri
data class CampaignAttribution(
val source: String?,
val medium: String?,
val campaign: String?
)
fun parseAttribution(uri: Uri): CampaignAttribution {
return CampaignAttribution(
source = uri.getQueryParameter("utm_source"),
medium = uri.getQueryParameter("utm_medium"),
campaign = uri.getQueryParameter("utm_campaign")
)
}
این داده ها می توانند در کلاینت های تحلیل آماری ثبت شده و گزارش های دقیقی از قیف فروش به تیم بازاریابی تحویل دهند.
۱۳. عیب یابی و اعتبارسنجی وضعیت App Links با دستورات ADB
یکی از خسته کننده ترین بخش های تست دیپ لینک ها، انتظار برای اعتبارسنجی خودکار توسط سیستم عامل است. با استفاده از ابزار پل دیباگ اندروید (ADB)، می توانید وضعیت تایید دامنه ها را در کسری از ثانیه بررسی و آزمایش کنید.
دستور اول: بررسی وضعیت تایید دامنه های پکیج برنامه
adb shell pm get-app-links com.example.myapp
در خروجی این دستور، دامنه ها باید وضعیت verified را نمایش دهند. اگر وضعیتی نظیر 1024 یا failed مشاهده کردید، نشان دهنده عدم دسترسی به فایل JSON سرور یا خطای گواهی SSL است.
دستور دوم: شبیه سازی باز شدن دیپ لینک از طریق ترمینال
adb shell am start -W -a android.intent.action.VIEW -d "https://example.com/products/890" com.example.myapp
این دستور یک پیام سیستم عامل صادر می کند که باعث باز شدن بلادرنگ اپلیکیشن و ناوبری به صفحه محصول مشخص شده می گردد، بدون نیاز به ارسال لینک در تلگرام یا یادداشت های گوشی.
برای مدیریت بهینه کارهای غیرهمگام حین پردازش لینک ها در پس زمینه، راهنمای مدیریت همزمانی در کاتلین با کورتین ها را در ساختار برنامه به کار بگیرید.
۱۴. آزمون های خودکار و تست نویسی دیپ لینک ها در پایپ لاین CI/CD
تضمین اینکه مسیرهای ناوبری با تغییر نسخه های بعدی پروژه شکسته نمی شوند، نیازمند نوشتن تست های واحد و آزمون های رابط کاربری است. با استفاده از آرتیفکت navigation-testing شما می توانید رفتار کنترلر ناوبری را در برابر Intent های دیپ لینک اعتبارسنجی کنید.
import androidx.navigation.testing.TestNavHostController
import androidx.test.core.app.ApplicationProvider
import org.junit.Test
import kotlin.test.assertEquals
class DeepLinkNavigationTest {
@Test
fun deepLink_resolvesToCorrectProductScreen() {
val navController = TestNavHostController(ApplicationProvider.getApplicationContext())
// شبیه سازی دریافت درخواست دیپ لینک معتبر
navController.navigate("product_detail/450")
assertEquals("product_detail/{productId}", navController.currentBackStackEntry?.destination?.route)
}
}
جهت مشاهده ساختارهای جامع تست نویسی واحد و کامپوننت ها با ابزار های شبیه ساز، مقاله آموزش تست نویسی در اندروید با MockK را مطالعه بفرمایید.
۱۵. اشتباهات مرگبار در پیاده سازی App Links و هشدارهای امنیتی
در پیاده سازی پیوندهای عمیق در اپلیکیشن های با میلیون ها نصب، رعایت نکات زیر از بروز حوادث امنیتی جلوگیری می کند:
- اعتبارسنجی سخت گیرانه ورودی ها (Input Sanitization): هرگز داده های دریافتی از پارامترهای URL را بدون بررسی اعتبار در کوئری های دیتابیس یا فرامین سیستمی اجرا نکنید؛ زیرا لینک ها می توانند حامل حملات تزریق کد باشند.
- پرهیز از ریدایرکت های ۳۰۱ و ۳۰۲ برای assetlinks.json: سیستم عامل اندروید ریدایرکت ها را در زمان دریافت فایل تایید دامنه دنبال نمی کند و فرآیند اعتبارسنجی بلافاصله مردود اعلام می گردد.
- پشتیبانی از تمامی ساب دامین ها: اگر دامنه های شما شامل
www.example.comوexample.comهستند، هر دو دامنه باید به طور جداگانه در مانیفست و در فایل سرور معرفی شوند. - پایش لاگ های Play Console: گوگل در پنل توسعه دهندگان پلی کنسول در بخش Deep Links سلامت تمام دامنه ها را گزارش می کند و هشدارهای عدم تطابق را به سرعت مخابره می نماید.
۱۶. پروژه عملی: پیاده سازی سیستم ناوبری فروشگاهی با دیپ لینک در Compose
در این بخش یک معماری کامل ناوبری فروشگاهی با قابلیت دریافت دیپ لینک های تخفیف و جزئیات سفارش را پیاده سازی می کنیم:
import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navDeepLink
@Composable
fun StoreAppNavigation() {
val navController = rememberNavController()
NavHost(navController = navController, startDestination = "home") {
composable("home") {
HomeScreen()
}
composable(
route = "cart?coupon={couponCode}",
deepLinks = listOf(
navDeepLink { uriPattern = "https://example.com/cart?coupon={couponCode}" }
)
) { backStackEntry ->
val coupon = backStackEntry.arguments?.getString("couponCode")
CartScreen(appliedCoupon = coupon)
}
}
}
این ساختار به تیم های بازاریابی دیجیتال اجازه می دهد تا لینک های اختصاصی تخفیف را در قالب پیامک یا ایمیل ارسال کرده و کاربر با یک لمس، مستقیماً وارد صفحه سبد خرید با کوپن فعال گردد.
۱۷. همگام سازی آفلاین فرست و نگه داری وضعیت ناوبری در شرایط قطع اینترنت
هنگامی که کاربر روی یک دیپ لینک در حالت آفلاین کلیک می کند، برنامه نباید صفحه سفید یا خطای ارتباط با سرور نمایش دهد. با پیاده سازی الگوی Offline-First، ابتدا داده های کش شده از پایگاه داده محلی نمایش داده می شوند.
این رویکرد تضمین می کند که اپلیکیشن در هر شرایطی واکنش پذیر باقی بماند و کاربر بدون معطلی محتوای مورد نظر را مشاهده نماید.
۱۸. راهنمای مهاجرت از Firebase Dynamic Links به ساختار بومی App Links
با توجه به اعلام رسمی شرکت گوگل مبنی بر بازنشستگی کامل سرویس Firebase Dynamic Links، تیم های مهندسی ناچار به مهاجرت به راهکارهای جایگزین هستند. درک تفاوت ها و مسیر مهاجرت برای حفظ پیوندهای مارکتینگ حیاتی است.
راهکار پیشنهادی گوگل، استفاده ترکیبی از وب ریدایرکت های سرور و مکانیزم استاندارد Android App Links و iOS Universal Links است. به این ترتیب، کاربر در صورت نصب بودن برنامه مستقیماً به آن هدایت می شود و در غیر این صورت، صفحه فرود وب سایت یا لینک فروشگاه نرم افزار به او پیشنهاد می گردد.
با پیاده سازی این زیرساخت در وب سرور و استفاده از قابلیت های بومی سیستم عامل اندروید، نیاز به هرگونه کتابخانه واسط تجاری برطرف شده و وابستگی های خارجی پروژه کاهش می یابد.
پرسش های متداول و جمع بندی دیپ لینک در اندروید
تفاوت اصلی بین Deep Link و App Link در اندروید چیست؟
دیپ لینک یک مفهوم عمومی برای هر لینکی است که به داخل برنامه اشاره می کند (از جمله اسکیم های سفارشی). اما App Link یک لینک وب HTTPS استاندارد است که مالکیت دامنه آن از طریق فایل assetlinks.json اثبات شده و بدون نمایش دیالوگ انتخاب اپلیکیشن، مستقیماً در برنامه باز می شود.
چرا در اندروید ۱۲ به بعد دیپ لینک های وب سایت من در مرورگر باز می شوند؟
از اندروید ۱۲ به بعد گوگل دیالوگ انتخاب برنامه را برای وب لینک های عادی حذف کرده است. اگر می خواهید لینک شما در اپلیکیشن باز شود، حتماً باید فرآیند اعتبارسنجی Android App Links با ویژگی android:autoVerify="true" و بارگذاری فایل assetlinks.json را طی نمایید.
چگونه می توانم وضعیت اعتبارسنجی دامنه را در گوشی تستی بررسی کنم؟
با اجرای دستور adb shell pm get-app-links com.example.myapp در ترمینال می توانید وضعیت تایید دامنه های برنامه خود را مشاهده کنید. وضعیت verified نشان دهنده تایید موفقیت آمیز است.
آیا فایل assetlinks.json می تواند از ریدایرکت ۳۰۱ یا ۳۰۲ استفاده کند؟
خیر، سیستم عامل اندروید ریدایرکت ها را برای فایل اعتبارسنجی دنبال نمی کند. فایل باید با کد وضعیت ۲۰۰ مستقیم، تحت پروتکل HTTPS و با هدر Content-Type: application/json سرویس دهی شود.
آیا می توان چند اپلیکیشن مختلف را به یک دامنه وب متصل کرد؟
بله، فایل assetlinks.json در واقع یک آرایه JSON است و شما می توانید چند شیء مربوط به پکیج نیم ها و اثرانگشت های مختلف (مثلاً نسخه عادی و نسخه راننده یا نسخه استیجینگ) را درون آن تعریف کنید.
چگونه پارامترهای کوئری اختیاری را در Navigation Compose هندل کنیم؟
در الگوی آدرس دهی Navigation Compose می توانید از ساختار علامت سوال استفاده کنید، به عنوان مثال product?ref={referrer} که پارامتر را اختیاری در نظر می گیرد و در صورت عدم وجود مقدار در لینک، خطایی ایجاد نمی کند.
آیا برای ساب دامین های مختلف نیاز به فایل جداگانه است؟
بله، هر ساب دامین (مانند shop.example.com و blog.example.com) یک هاست مجزا تلقی می شود و فایل assetlinks.json باید روی روت همان ساب دامین نیز قرار داشته باشد و در مانیفست قید گردد.
چرا پس از انتشار در گوگل پلی، اعتبارسنجی دامنه شکست می خورد؟
اگر قابلیت Google Play App Signing فعال باشد، گوگل فایل باینری را با کلید انتشار اختصاصی خود امضا می کند. شما باید اثرانگشت SHA-۲۵۶ موجود در پنل پلی کنسول را برداشته و در فایل assetlinks.json سرور درج نمایید.
چک لیست نهایی و نکات کلیدی انتشار دیپ لینک های اندروید
assetlinks.json با وضعیت ۲۰۰ و بدون ریدایرکت، تطابق دقیق اثرانگشت SHA-۲۵۶، پیاده سازی مسیرهای navDeepLink در کامپوز، مدیریت singleTask برای متد onNewIntent و اعتبارسنجی با دستورات ADB.


امتیاز و نظرات
هنوز نظری ثبت نشده است. اولین نفر باشید.