Deep Linking Terpadu iOS
Sekilas: Tautan langsung terpadu/Unified deep linking (UDL) memungkinkan Anda untuk mengirim pengguna yang sudah ada dan yang baru ke aktivitas in-app tertentu (misalnya, laman tertentu di dalam aplikasi) segera setelah aplikasi dibuka.
Perlindungan privasi UDL
For new users, the UDL method only returns parameters relevant to deferred deep linking:
deep_link_value
anddeep_link_sub1-10
. If you try to get any other parameters (media_source
,campaign
,af_sub1-5
, dll.), mereka kembali ke null.
Alur
Alur kerjanya adalah sebagai berikut:
- Pengguna mengklik tautan OneLink.
- Jika pengguna telah menginstal aplikasi, Tautan Universal atau skema URI akan membuka aplikasi.
- Jika pengguna tidak menginstal aplikasi, mereka diarahkan ke app store, dan setelah mengunduh, pengguna membuka aplikasi.
- Pembukaan aplikasi memicu SDK AppsFlyer.
- SDK AppsFlyer menjalankan API UDL.
- API UDL mengambil data OneLink dari server AppsFlyer.
- The UDL API calls back the
didResolveDeepLink()
in theDeepLinkDelegate
. - The
didResolveDeepLink()
method gets aDeepLinkResult
object. - The
DeepLinkResult
object includes:- Status (Ditemukan/Tidak ditemukan/Gagal)
- A
DeepLink
object that carries thedeep_link_value
anddeep_link_sub1-10
parameters that the developer uses to route the user to a specific in-app activity, which is the main goal of OneLink.
Perencanaan
- UDL mewajibkan SDK AppsFlyer iOS V6.1+.
Saat mengatur OneLinks, pemasar menggunakan parameter untuk membuat tautan, dan programmer menyesuaikan perilaku aplikasi berdasarkan nilai yang diterima. Programmer bertanggung jawab untuk memastikan parameter ditangani dengan benar di aplikasi, baik untuk perutean dalam aplikasi dan mempersonalisasi data di tautan.
Untuk merencanakan OneLink:
- Dapatkan dari pemasar perilaku dan pengalaman pribadi yang diinginkan pengguna saat mereka mengklik URL.
- Based on the desired behavior, plan the
deep_link_value
and other parameters that are needed to give the user the desired personal experience.- The
deep_link_value
is set by the marketer in the URL and used by the developer to redirect the user to a specific place inside the app. For example, if you have a fruit store and want to direct users to apples, the value ofdeep_link_value
can beapples
. - The
deep_link_sub1-10
parameters can also be added to the URL to help personalize the user experience. For example, to give a 10% discount, the value ofdeep_link_sub1
can be10
.
- The
Penerapan
Let's save you some time >>
Set Deep Linking with our SDK integration wizard
Menerapkan logika API UDL berdasarkan parameter dan nilai yang dipilih.
- Assign the
AppDelegate
usingself
toAppsFlyerLib.shared().deepLinkDelegate
. - Terapkan fungsi aplikasi untuk memungkinkan:
- Dukungan Tautan Universal dengan
continue
. - Dukungan skema URI dengan
handleOpen
.
- Dukungan Tautan Universal dengan
- Create
DeepLinkDelegate
as an extension ofAppDelegate
. - Add
application
functions to support Universal Links and URI schemes. - In
DeepLinkDelegate
, make sure you override the callback function,didResolveDeepLink()
.
didResolveDeepLink()
accepts aDeepLinkResult
object as an argument. - Use
DeepLinkResult.status
to query whether the deep linking match is found. - For when the status is an error, call
DeepLinkResult.error
and run your error flow. - For when the status is found, use
DeepLinkResult.deepLink
to retrieve theDeepLink
object.
TheDeepLink
object contains the deep linking information arranged in public variables to retrieve the values from well-known OneLink keys, for example,DeepLink.deeplinkValue
fordeep_link_value
. - Use
deepLinkObj.clickEvent["deep_link_sub1"]
to retrievedeep_link_sub1
. Do the same fordeep_link_sub2-10
parameters, changing the string value as required. - Once
deep_link_value
anddeep_link_sub1-10
are retrieved, pass them to an in-app router and use them to personalize the user experience.
Supporting legacy OneLink links
Tautan OneLink lawas adalah tautan yang tidak berisi parameter yang disarankan untuk Deep Linking Terpadu: deep_link_value
and deep_link_sub1-10
.
Biasanya ini adalah tautan yang sudah ada dan sedang digunakan saat bermigrasi dari metode lawas ke UDL.
Pengguna berita yang menggunakan tautan lawas ditangani oleh onConversionDataSuccess
dalam konteks deferred deep linking yang diperluas.
UDL menangani deep linking untuk pengguna yang sudah ada. Anda disarankan untuk menambahkan dukungan di panggilan balik UDL didResolveDeepLink
untuk parameter lawas.
Contoh kode swift
Code example
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Replace 'appleAppID' and 'appsFlyerDevKey' with your Apple App ID (eg 69999999, without id prefix) and DevKey
// The App ID and the DevKey must be set prior to the calling of the deepLinkDelegate
AppsFlyerLib.shared().appleAppID = appleAppID
AppsFlyerLib.shared().appsFlyerDevKey = appsFlyerDevKey
...
AppsFlyerLib.shared().deepLinkDelegate = self
...
}
// For Swift version < 4.2 replace function signature with the commented out code
// func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool { // this line for Swift < 4.2
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
AppsFlyerLib.shared().continue(userActivity, restorationHandler: nil)
return true
}
// Open URI-scheme for iOS 9 and above
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
AppsFlyerLib.shared().handleOpen(url, options: options)
return true
}
extension AppDelegate: DeepLinkDelegate {
func didResolveDeepLink(_ result: DeepLinkResult) {
var fruitNameStr: String?
switch result.status {
case .notFound:
NSLog("[AFSDK] Deep link not found")
return
case .failure:
print("Error %@", result.error!)
return
case .found:
NSLog("[AFSDK] Deep link found")
}
guard let deepLinkObj:DeepLink = result.deepLink else {
NSLog("[AFSDK] Could not extract deep link object")
return
}
if deepLinkObj.clickEvent.keys.contains("deep_link_sub2") {
let ReferrerId:String = deepLinkObj.clickEvent["deep_link_sub2"] as! String
NSLog("[AFSDK] AppsFlyer: Referrer ID: \(ReferrerId)")
} else {
NSLog("[AFSDK] Could not extract referrerId")
}
let deepLinkStr:String = deepLinkObj.toString()
NSLog("[AFSDK] DeepLink data is: \(deepLinkStr)")
if( deepLinkObj.isDeferred == true) {
NSLog("[AFSDK] This is a deferred deep link")
}
else {
NSLog("[AFSDK] This is a direct deep link")
}
fruitNameStr = deepLinkObj.deeplinkValue
walkToSceneWithParams(fruitName: fruitNameStr!, deepLinkData: deepLinkObj.clickEvent)
}
}
// User logic
fileprivate func walkToSceneWithParams(deepLinkObj: DeepLink) {
let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true, completion: nil)
guard let fruitNameStr = deepLinkObj.clickEvent["deep_link_value"] as? String else {
print("Could not extract query params from link")
return
}
let destVC = fruitNameStr + "_vc"
if let newVC = storyBoard.instantiateVC(withIdentifier: destVC) {
print("AppsFlyer routing to section: \(destVC)")
newVC.deepLinkData = deepLinkObj
UIApplication.shared.windows.first?.rootViewController?.present(newVC, animated: true, completion: nil)
} else {
print("AppsFlyer: could not find section: \(destVC)")
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Set isDebug to true to see AppsFlyer debug logs
[AppsFlyerLib shared].isDebug = YES;
// Replace 'appsFlyerDevKey', `appleAppID` with your DevKey, Apple App ID
[AppsFlyerLib shared].appsFlyerDevKey = appsFlyerDevKey;
[AppsFlyerLib shared].appleAppID = appleAppID;
[AppsFlyerLib shared].deepLinkDelegate = self;
return YES;
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler {
[[AppsFlyerLib shared] continueUserActivity:userActivity restorationHandler:nil];
return YES;
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
[[AppsFlyerLib shared] handleOpenUrl:url options:options];
return YES;
}
#pragma mark - DeepLinkDelegate
- (void)didResolveDeepLink:(AppsFlyerDeepLinkResult *)result {
NSString *fruitNameStr;
NSLog(@"[AFSDK] Deep link lowkehy");
switch (result.status) {
case AFSDKDeepLinkResultStatusNotFound:
NSLog(@"[AFSDK] Deep link not found");
return;
case AFSDKDeepLinkResultStatusFailure:
NSLog(@"Error %@", result.error);
return;
case AFSDKDeepLinkResultStatusFound:
NSLog(@"[AFSDK] Deep link found");
break;
}
AppsFlyerDeepLink *deepLinkObj = result.deepLink;
if ([deepLinkObj.clickEvent.allKeys containsObject:@"deep_link_sub2"]) {
NSString *referrerId = deepLinkObj.clickEvent[@"deep_link_sub2"];
NSLog(@"[AFSDK] AppsFlyer: Referrer ID: %@", referrerId);
} else {
NSLog(@"[AFSDK] Could not extract referrerId");
}
NSString *deepLinkStr = [deepLinkObj toString];
NSLog(@"[AFSDK] DeepLink data is: %@", deepLinkStr);
if (deepLinkObj.isDeferred) {
NSLog(@"[AFSDK] This is a deferred deep link");
if (self.deferredDeepLinkProcessedFlag) {
NSLog(@"Deferred deep link was already processed by GCD. This iteration can be skipped.");
self.deferredDeepLinkProcessedFlag = NO;
return;
}
} else {
NSLog(@"[AFSDK] This is a direct deep link");
}
fruitNameStr = deepLinkObj.deeplinkValue;
// If deep_link_value doesn't exist
if (!fruitNameStr || [fruitNameStr isEqualToString:@""]) {
// Check if fruit_name exists
id fruitNameValue = deepLinkObj.clickEvent[@"fruit_name"];
if ([fruitNameValue isKindOfClass:[NSString class]]) {
fruitNameStr = (NSString *)fruitNameValue;
} else {
NSLog(@"[AFSDK] Could not extract deep_link_value or fruit_name from deep link object with unified deep linking");
return;
}
}
// This marks to GCD that UDL already processed this deep link.
// It is marked to both DL and DDL, but GCD is relevant only for DDL
self.deferredDeepLinkProcessedFlag = YES;
[self walkToSceneWithParams:fruitNameStr deepLinkData:deepLinkObj.clickEvent];
}
- (void)walkToSceneWithParams:(NSString *)fruitName deepLinkData:(NSDictionary *)deepLinkData {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
[[UIApplication sharedApplication].windows.firstObject.rootViewController dismissViewControllerAnimated:YES completion:nil];
NSString *destVC = [fruitName stringByAppendingString:@"_vc"];
DLViewController *newVC = [storyboard instantiateViewControllerWithIdentifier:destVC];
NSLog(@"[AFSDK] AppsFlyer routing to section: %@", destVC);
newVC.deepLinkData = deepLinkData;
[[UIApplication sharedApplication].windows.firstObject.rootViewController presentViewController:newVC animated:YES completion:nil];
}
⇲ Github links: Swift
⇲ Github links: Objective-C
Deferred Deep Linking after network consent
In some cases the application might require consent from the user in order to connect to the network, in a dialog similar to this one:

In order to support deferred deep linking once the network consent is given we recommend:
- Implement eDDL to allow UDL to handle the deferred deep linking
Menguji deferred deep linking
Prerequisites
- Selesaikan integrasi UDL.
- Daftarkan perangkat pengujian Anda .
- Aktifkan mode debug di aplikasi.
- Pastikan aplikasi tidak terpasang di perangkat Anda.
- Minta pemasar Anda untuk templat OneLink.
- Ini akan terlihat seperti ini:
https://onelink-basic-app.onelink.me/H5hv
. - Contoh ini menggunakan subdomain OneLink
onelink-basic-app.onelink.me
dan ID templat OneLinkH5hv
.
- Ini akan terlihat seperti ini:
The test link
Anda dapat menggunakan tautan OneLink yang ada atau meminta pemasar Anda untuk membuat tautan baru untuk pengujian. URL OneLink pendek dan panjang dapat digunakan.
Menambahkan parameter ad-hoc ke tautan yang ada
- Gunakan hanya domain dan templat OneLink dari tautan Anda. Contoh:
https://onelink-basic-app.onelink.me/H5hv
. - Tambahkan parameter OneLink
deep_link_value
anddeep_link_sub1-10
seperti yang diharapkan oleh aplikasi Anda. Parameter harus ditambahkan sebagai parameter kueri.- Contoh:
https://onelink-basic-app.onelink.me/H5hv?pid=my_media_source&deep_link_value=apples&deep_link_sub1=23
- Contoh:
Perform the test
- Klik tautan di perangkat Anda.
- OneLink mengarahkan Anda sesuai dengan pengaturan tautan, ke App Store atau situs web.
- Instal aplikasi.
Penting
- Jika aplikasi masih dalam pengembangan, dan belum diunggah ke toko, Anda akan melihat gambar ini:
- Instal aplikasi dari Xcode.
- Jika aplikasi masih dalam pengembangan, dan belum diunggah ke toko, Anda akan melihat gambar ini:
- UDL mendeteksi penautan dalam yang ditangguhkan, mencocokkan penginstalan dengan klik, dan mengambil parameter OneLink ke
didResolveDeepLink
callback.
Expected logs results
Log berikut hanya tersedia bila mode debug diaktifkan.
- SDK diinisialisasi:
[AppsFlyerSDK] [com.apple.main-thread] AppsFlyer SDK version 6.6.0 started build
- UDL API mulai:
D/AppsFlyer_6.9.0: [DDL] start
- UDL mengirimkan kueri ke AppsFlyer untuk menanyakan kecocokan dengan penginstalan ini:
[AppsFlyerSDK] [com.appsflyer.serial] [DDL] URL: https://dlsdk.appsflyer.com/v1.0/ios/id1512793879?sdk_version=6.6&af_sig=efcecc2bc95a0862ceaa7b62fa8e98ae1e3e022XXXXXXXXXXXXXXXX
- UDL mendapat tanggapan dan panggilan
didResolveDeepLink
callback denganstatus=FOUND
dan data tautan OneLink:[AppsFlyerSDK] [com.appsflyer.serial] [DDL] Calling didResolveDeepLink with: {"af_sub4":"","click_http_referrer":"","af_sub1":"","click_event":{"af_sub4":"","click_http_referrer":"","af_sub1":"","af_sub3":"","deep_link_value":"peaches","campaign":"","match_type":"probabilistic","af_sub5":"","campaign_id":"","media_source":"","deep_link_sub1":"23","af_sub2":""},"af_sub3":"","deep_link_value":"peaches","campaign":"","match_type":"probabilistic","af_sub5":"","media_source":"","campaign_id":"","af_sub2":""}
Menguji deep linking (Universal Links)
Prerequisites
- Selesaikan integrasi UDL.
- Daftarkan perangkat pengujian Anda .
- Aktifkan mode debug di aplikasi.
- Pastikan aplikasi sudah terpasang di perangkat Anda
- Minta pemasar Anda templat OneLink.
- Ini akan terlihat seperti ini:
https://onelink-basic-app.onelink.me/H5hv
. - Contoh ini menggunakan subdomain OneLink
onelink-basic-app.onelink.me
dan ID templat OneLinkH5hv
- Ini akan terlihat seperti ini:
- Konfigurasikan Tautan Universal.
Create the test link
Gunakan metode yang sama seperti pada deferred deep linking.
Perform the test
- Klik tautan di perangkat Anda.
- UDL mendeteksi Tautan Universal dan mengambil parameter OneLink ke
didResolveDeepLink
callback.
Expected logs results
Log berikut hanya tersedia bila mode debug diaktifkan.
- Jika tautannya adalah tautan pendek OneLink (mis. https://onelink-basic-app.onelink.me/H5hv/apples):
[AppsFlyerSDK] [com.apple.main-thread] NSUserActivity `webpageURL`: https://onelink-basic-app.onelink.me/H5hv/apples [AppsFlyerSDK] [com.appsflyer.serial] UniversalLink/Deeplink found: https://onelink-basic-app.onelink.me/H5hv/apples [AppsFlyerSDK] [com.appsflyer.serial] Shortlink found. Executing: https://onelink.appsflyer.com/shortlink-sdk/v2/H5hv?id=apples ... [AppsFlyerSDK] [com.appsflyer.serial] [Shortlink] OneLink:{ c = test1; campaign = test1; "deep_link_sub1" = 23; "deep_link_value" = peaches; "is_retargeting" = true; "media_source" = SMS; pid = SMS; }
- UDL memanggil
didResolveDeepLink
callback denganstatus=FOUND
dan data tautan OneLink:[AppsFlyerSDK] [com.appsflyer.serial] [DDL] Calling didResolveDeepLink with: {"af_sub4":null,"click_http_referrer":null,"af_sub1":null,"click_event":{"campaign":"test1","deep_link_sub1":"23","deep_link_value":"peaches","media_source":"SMS"},"af_sub3":null,"deep_link_value":"peaches","campaign":"test1","match_type":null,"af_sub5":null,"media_source":"SMS","campaign_id":null,"af_sub2":null}
Diperbarui 29 hari yang lalu