当已安装应用的用户点击 Adjust 链接时,直接深度链接可确保将用户直接转到应用内的特定内容。
设置
iOS 提供了多种接收直接深度链接的方法,具体取决于应用的实施方式。
在这些方法中,您将使用下列其中一种方法将深度链接传递给 Adjust SDK:
处理并解析深度链接 (推荐)
使用processDeeplink(_:completionHandler:)方法,该方法会执行以下操作:
- 记录深度链接点击的归因
- 将品牌化短链接解析为其等效的品牌化长链接
- 按原样透传所有其他链接
然后,应用可以通过解析已解析的链接并跳转至相应的界面来处理该链接。可以使用此方法处理所有深度链接,包括 Adjust 品牌化长链接、其他通用链接以及应用 Scheme 深度链接。
+ (void)processDeeplink:(nonnull NSURL *)deeplink completionHandler:(void (^_Nonnull)(NSString * _Nonnull resolvedLink))completionHandler;处理深度链接 (旧版)
如果您使用的不是短品牌化链接,那么 appWillOpen(_:) 方法就会记录来自深度链接点击的归因。
+ (void)appWillOpenUrl:(nonnull NSURL *)url;processDeeplink(_:completionHandler:) 方法会取代该遗留方法。
实施
使用与应用结构相符的实施方式:
- 使用 AppDelegate 生命周期的 UIKit 应用
- 使用 SceneDelegate 生命周期的 UIKit 应用
- 使用 AppDelegate 生命周期的 SwiftUI 应用
- 使用 SceneDelegate 生命周期的 SwiftUI 应用
使用 AppDelegate 生命周期的 UIKit 应用
更新 AppDelegate 以实施 iOS 直接深度链接方法。
1// Receive universal link when app is installed2// and link opens app from "Not Running"3// or Background state.4func application(5 _ application: UIApplication,6 continue userActivity: NSUserActivity,7 restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void8) -> Bool {9 guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,10 let incomingLink = userActivity.webpageURL11 else { return true }12
13 print("[IncomingLink] application:continueUserActivity: url=\(incomingLink.absoluteString)")14
15 // Send deep link to Adjust's servers for attribution.16 // If short branded link, receive long link.17 // Otherwise, receive original link.18 Adjust.processDeeplink(incomingLink) { resolvedLink in19 // Handle failure if resolvedLink is nil20 guard let resolvedLink = resolvedLink else { return }21
22 /*23 Possible resolvedLink formats:24
25 1. https://brandname.go.link/?adj_t=def456&26 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach27 - Extract and decode the deep link from the 'adj_link' query parameter.28
29 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45630 - Extract the path and relevant query parameters directly from the URL.31
32 TODO: Handle the deep link and navigate to the appropriate screen.33 */34 }35
36 return true37}38
39// Receive app scheme deep link when app is installed40// and link opens app from "Not Running",41// Background, or Foreground state.42func application(43 _ application: UIApplication,44 open incomingLink: URL,45 options: [UIApplication.OpenURLOptionsKey: Any] = [:]46) -> Bool {47 print("[IncomingLink] application:openURL: url=\(incomingLink)")48
49 // Send deep link to Adjust's servers for attribution.50 // If short branded link, receive long link.51 // Otherwise, receive original link.52 Adjust.processDeeplink(incomingLink) { resolvedLink in53 // Handle failure if resolvedLink is nil54 guard let resolvedLink = resolvedLink else { return }55
56 /*57 resolvedLink format:58
59 example://summer-clothes?promo=beach&adj_t=def45660 - Extract the path and relevant query parameters directly from the URL.61
62 TODO: Handle the deep link and navigate to the appropriate screen.63 */64 }65 return true66}1// Receive universal link when app is installed2// and link opens app from "Not Running"3// or Background state.4- (BOOL)application:(UIApplication *)application5 continueUserActivity:(NSUserActivity *)userActivity6 restorationHandler:7 (void (^)(NSArray<id<uiuseractivityrestoring>> *_Nullable))8 restorationHandler {9 // Check if it's a web browsing activity10 if (![userActivity.activityType11 isEqualToString:NSUserActivityTypeBrowsingWeb])12 return YES;13
14 // Check if there's a valid URL15 NSURL *incomingLink = userActivity.webpageURL;16 if (!incomingLink) return YES;17
18 // Send deep link to Adjust's servers for attribution.19 // If short branded link, receive long link.20 // Otherwise, receive original link.21 [Adjust processDeeplink:incomingLink22 completionHandler:^(NSString *resolvedLink){23 if (!resolvedLink) return;24
25 /*26 Possible resolvedLink formats:27
28 1. https://brandname.go.link/?adj_t=def456&29 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach30 - Extract and decode the deep link from the 'adj_link' query parameter.31
32 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45633 - Extract the path and relevant query parameters directly from the URL.34
35 TODO: Handle the deep link and navigate to the appropriate screen.36 */37 }];38
39 return YES;40}41
42// Receive app scheme deep link when app is installed43// and link opens app from "Not Running",44// Background, or Foreground state.45- (BOOL)application:(UIApplication *)application46 openURL:(NSURL *)incomingLink47 options:48 (NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {49 // Send deep link to Adjust's servers for attribution.50 // If short branded link, receive long link.51 // Otherwise, receive original link.52 [Adjust processDeeplink:incomingLink53 completionHandler:^(NSString *resolvedLink){54 if (!resolvedLink) return;55
56 /*57 resolvedLink format:58
59 example://summer-clothes?promo=beach&adj_t=def45660 - Extract the path and relevant query parameters directly from the URL.61
62 TODO: Handle the deep link and navigate to the appropriate screen.63 */64 }];65 return YES;66}使用 SceneDelegate 生命周期的 UIKit 应用
更新 SceneDelegate 以实施 iOS 直接深度链接方法。
1// Receive universal link or app scheme deep link when app is installed2// and link opens app from "Not Running" state.3func scene(4 _ scene: UIScene,5 willConnectTo session: UISceneSession,6 options connectionOptions: UIScene.ConnectionOptions7) {8 // Receive incoming universal link9 if let userActivity = connectionOptions.userActivities.first,10 userActivity.activityType == NSUserActivityTypeBrowsingWeb,11 let incomingLink = userActivity.webpageURL12 {13 print("[IncomingLink] scene:willConnectToSession:options: url=\(incomingLink.absoluteString)")14
15 // Send deep link to Adjust's servers for attribution.16 // If short branded link, receive long link.17 // Otherwise, receive original link.18 Adjust.processDeeplink(incomingLink) { resolvedLink in19 // Handle failure if resolvedLink is nil20 guard let resolvedLink = resolvedLink else { return }21
22 /*23 Possible resolvedLink formats:24
25 1. https://brandname.go.link/?adj_t=def456&26 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach27 - Extract and decode the deep link from the 'adj_link' query parameter.28
29 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45630 - Extract the path and relevant query parameters directly from the URL.31
32 TODO: Handle the deep link and navigate to the appropriate screen.33 */34 }35 return36 }37
38 // Receive incoming app scheme deep link39 guard let incomingLink = connectionOptions.urlContexts.first?.url else { return }40
41 print("[IncomingLink] scene:willConnectToSession:options: url=\(incomingLink.absoluteString)")42
43 // Send deep link to Adjust's servers for attribution.44 // If short branded link, receive long link.45 // Otherwise, receive original link.46 Adjust.processDeeplink(incomingLink) { resolvedLink in47 // Handle failure if resolvedLink is nil48 guard let resolvedLink = resolvedLink else { return }49
50 /*51 resolvedLink format:52
53 example://summer-clothes?promo=beach&adj_t=def45654 - Extract the path and relevant query parameters directly from the URL.55
56 TODO: Handle the deep link and navigate to the appropriate screen.57 */58 }59}60
61// Receive universal link when app is installed62// and link opens app from Background state.63func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {64 guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,65 let incomingLink = userActivity.webpageURL66 else { return }67
68 print("[IncomingLink] scene:continueUserActivity: url=\(incomingLink.absoluteString)")69
70 // Send deep link to Adjust's servers for attribution.71 // If short branded link, receive long link.72 // Otherwise, receive original link.73 Adjust.processDeeplink(incomingLink) { resolvedLink in74 // Handle failure if resolvedLink is nil75 guard let resolvedLink = resolvedLink else { return }76
77 /*78 Possible resolvedLink formats:79
80 1. https://brandname.go.link/?adj_t=def456&81 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach82 - Extract and decode the deep link from the 'adj_link' query parameter.83
84 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45685 - Extract the path and relevant query parameters directly from the URL.86
87 TODO: Handle the deep link and navigate to the appropriate screen.88 */89 }90}91
92// Receive app scheme deep link when app is installed93// and link opens app from Background94// or Foreground state.95func scene(96 _ scene: UIScene,97 openURLContexts URLContexts: Set<uiopenurlcontext>98) {99 guard let incomingLink = URLContexts.first?.url else { return }100
101 print("[IncomingLink] scene:openURLContexts: url=\(incomingLink.absoluteString)")102
103 // Send deep link to Adjust's servers for attribution.104 // If short branded link, receive long link.105 // Otherwise, receive original link.106 Adjust.processDeeplink(incomingLink) { resolvedLink in107 // Handle failure if resolvedLink is nil108 guard let resolvedLink = resolvedLink else { return }109
110 /*111 resolvedLink format:112
113 example://summer-clothes?promo=beach&adj_t=def456114 - Extract the path and relevant query parameters directly from the URL.115
116 TODO: Handle the deep link and navigate to the appropriate screen.117 */118 }119}1// Receive universal link or app scheme deep link when app is installed2// and link opens app from "Not Running" state.3- (void)scene:(UIScene *)scene4 willConnectToSession:(UISceneSession *)session5 options:(UISceneConnectionOptions *)connectionOptions {6 // Receive universal link7 if (connectionOptions.userActivities.count > 0) {8 NSUserActivity *userActivity =9 connectionOptions.userActivities.allObjects.firstObject;10 if ([userActivity.activityType11 isEqualToString:NSUserActivityTypeBrowsingWeb] &&12 userActivity.webpageURL) {13 NSURL *incomingLink = userActivity.webpageURL;14 // Send deep link to Adjust's servers for attribution.15 // If short branded link, receive long link.16 // Otherwise, receive original link.17 [Adjust processDeeplink:incomingLink18 completionHandler:^(NSString *resolvedLink){19 if (!resolvedLink) return;20
21 /*22 Possible resolvedLink formats:23
24 1. https://brandname.go.link/?adj_t=def456&25 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach26 - Extract and decode the deep link from the 'adj_link' query parameter.27
28 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45629 - Extract the path and relevant query parameters directly from the URL.30
31 TODO: Handle the deep link and navigate to the appropriate screen.32 */33 }];34 return;35 }36 }37
38 // Receive app scheme deep link39 if (connectionOptions.URLContexts.count == 0) return;40
41 UIOpenURLContext *urlContext =42 connectionOptions.URLContexts.allObjects.firstObject;43 NSURL *incomingLink = urlContext.URL;44
45 // Send deep link to Adjust's servers for attribution.46 // If short branded link, receive long link.47 // Otherwise, receive original link.48 [Adjust processDeeplink:incomingLink49 completionHandler:^(NSString *resolvedLink){50 if (!resolvedLink) return;51
52 /*53 resolvedLink format:54
55 example://summer-clothes?promo=beach&adj_t=def45656 - Extract the path and relevant query parameters directly from the URL.57
58 TODO: Handle the deep link and navigate to the appropriate screen.59 */60 }];61}62
63// Receive universal link when app is installed64// and link opens app from Background state.65- (void)scene:(UIScene *)scene66 continueUserActivity:(NSUserActivity *)userActivity {67 // Check if it's a web browsing activity68 if (![userActivity.activityType69 isEqualToString:NSUserActivityTypeBrowsingWeb])70 return;71
72 // Check if there's a valid URL73 NSURL *incomingLink = userActivity.webpageURL;74 if (!incomingLink) return;75
76 // Send deep link to Adjust's servers for attribution.77 // If short branded link, receive long link.78 // Otherwise, receive original link.79 [Adjust processDeeplink:incomingLink80 completionHandler:^(NSString *resolvedLink){81 if (!resolvedLink) return;82
83 /*84 Possible resolvedLink formats:85
86 1. https://brandname.go.link/?adj_t=def456&87 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach88 - Extract and decode the deep link from the 'adj_link' query parameter.89
90 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45691 - Extract the path and relevant query parameters directly from the URL.92
93 TODO: Handle the deep link and navigate to the appropriate screen.94 */95 }];96}97
98// Receive app scheme deep link when app is installed99// and link opens app from Background100// or Foreground state.101- (void)scene:(UIScene *)scene102 openURLContexts:(NSSet<uiopenurlcontext *> *)URLContexts {103 // Check if we have any URL contexts104 UIOpenURLContext *urlContext = URLContexts.allObjects.firstObject;105 if (!urlContext) return;106
107 // Check if the URL is valid108 NSURL *incomingLink = urlContext.URL;109 if (!incomingLink) return;110
111 // Send deep link to Adjust's servers for attribution.112 // If short branded link, receive long link.113 // Otherwise, receive original link.114 [Adjust processDeeplink:incomingLink115 completionHandler:^(NSString *resolvedLink){116 if (!resolvedLink) return;117
118 /*119 resolvedLink format:120
121 example://summer-clothes?promo=beach&adj_t=def456122 - Extract the path and relevant query parameters directly from the URL.123
124 TODO: Handle the deep link and navigate to the appropriate screen.125 */126 }];127}使用 AppDelegate 生命周期的 SwiftUI 应用
如果尚未在项目的主目录中创建 AppDelegate.swift 文件,请立即执行此操作,并在主应用文件中加以引用,如以下 App.swift 示例文件所示。这是处理应用生命周期事件和 Adjust SDK 集成的必要步骤。此外,实施 onOpenURL SwiftUI 修饰符,该修饰符在应用安装时接收通用链接和应用 Scheme 深度链接。
1import Adjust2import SwiftUI3
4@main5struct MyApp: App {6 @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate7
8 var body: some Scene {9 WindowGroup {10 ContentView()11 // Receive universal link or app scheme deep link when app is installed12 // and link opens app from "Not Running",13 // Background, or Foreground state.14 .onOpenURL { incomingLink in15 print("[IncomingLink] onOpenURL: url=\(incomingLink.absoluteString)")16
17 // Send deep link to Adjust's servers for attribution.18 // If short branded link, receive long link.19 // Otherwise, receive original link.20 Adjust.processDeeplink(incomingLink) { resolvedLink in21 // Handle failure if resolvedLink is nil22 guard let resolvedLink = resolvedLink else { return }23
24 /*25 Possible resolvedLink formats:26
27 1. https://brandname.go.link/?adj_t=def456&28 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach29 - Extract and decode the deep link from the 'adj_link' query parameter.30
31 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45632 - Extract the path and relevant query parameters directly from the URL.33
34 3. example://summer-clothes?promo=beach&adj_t=def45635 - Extract the path and relevant query parameters directly from the URL.36
37 TODO: Handle the deep link and navigate to the appropriate screen.38 */39 }40 }41 }42 }43}使用 SceneDelegate 生命周期的 SwiftUI 应用
按照“使用 AppDelegate 生命周期的 SwiftUI 应用”栏中的说明进行操作。安装应用后,onOpenURL SwiftUI 修饰符会接收通用链接和应用 Scheme 深度链接,并且该链接会在后台或前台状态中打开相关应用。
此外,从“使用 SceneDelegate 生命周期的 UIKit 应用”栏实施scene(_:willConnectTo:options:)方法。此方法会在安装应用后接收通用链接和应用 Scheme 深度链接,并且该链接会在“未运行”状态中打开相关应用。
前台导航
如果您将 Adjust 深度链接放置在自己的应用中,例如促销横幅或产品推荐等,请不要对其调用 UIApplication.open(_:options:completionHandler:) 或 SwiftUI 的 openURL 。iOS 会在 Safari 中打开应用的通用链接,不会在应用内发送这些链接。请改为通过 processDeeplink 发送链接,然后使用与本页所述相同的处理路径,发送已解析的深度链接。