앱이 설치된 사용자가 Adjust 링크를 클릭하면 다이렉트 딥링킹을 통해 앱 내의 특정 콘텐츠로 바로 이동할 수 있습니다.
설정
iOS는 앱 구현에 따라 다이렉트 딥링크를 수신하는 몇 가지 메서드를 제공합니다. 이러한 메서드에 따라 다음 메서드 중 하나를 사용하여 Adjust SDK에 딥링크를 전달할 수 있습니다.
딥링크 처리 및 확인(권장)
processAndResolve(_:withCompletionHandler:) 메서드를 사용하여 다음 작업을 수행합니다.
- 딥링크 클릭에서 어트리뷰션 기록
- 짧은 브랜드 링크를 해당 긴 브랜드 링크로 변환
- 다른 모든 링크를 그대로 전달
앱은 해결된 링크를 분석하여 적절한 화면으로 이동함으로써 처리할 수 있습니다. Adjust의 긴 브랜드 링크, 기타 유니버설 링크, 앱 스킴 딥링크를 포함한 모든 딥링크에 이 메서드를 사용할 수 있습니다.
+ (void)processAndResolveDeeplink:(nonnull ADJDeeplink *)deeplink withCompletionHandler:(nonnull ADJResolvedDeeplinkBlock)completion;딥링크 처리(레거시)
processDeeplink(_:) 메서드는 단축 브랜드 링크를 사용하지 않는 경우 딥링크 클릭으로부터의 어트리뷰션을 기록합니다.
+ (void)processDeeplink:(ADJDeeplink *)deeplink;processAndResolve(_:withCompletionHandler:) 메서드가 이 레거시 메서드를 대체합니다.
구현
앱의 구조에 맞는 구현을 사용하세요.
- AppDelegate 라이프사이클을 사용하는 UIKit 앱
- SceneDelegate 라이프사이클을 사용하는 UIKit 앱
- AppDelegate 라이프사이클을 사용하는 SwiftUI 앱
- SceneDelegate 라이프사이클을 사용하는 SwiftUI 앱
AppDelegate 라이프사이클을 사용하는 UIKit 앱
iOS 다이렉트 딥링킹 메서드를 구현하려면 AppDelegate를 업데이트하세요.
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 // Create deep link object16 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return false }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.processAndResolve(deeplink) { resolvedLink in22 // Handle failure if resolvedLink is nil23 guard let resolvedLink = resolvedLink else { return }24
25 /*26 TODO: Handle the deep link and navigate to the appropriate screen.27
28 Possible resolvedLink formats:29
30 1. https://brandname.go.link/?adj_t=def456&31 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach32 - Extract and decode the deep link from the 'adj_link' query parameter.33
34 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45635 - Extract the path and relevant query parameters directly from the URL.36 */37 }38
39 return true40}41
42// Receive app scheme deep link when app is installed43// and link opens app from "Not Running",44// Background, or Foreground state.45func application(46 _ application: UIApplication,47 open incomingLink: URL,48 options: [UIApplication.OpenURLOptionsKey: Any] = [:]49) -> Bool {50 print("[IncomingLink] application:openURL: url=\(incomingLink)")51
52 // Create deep link object53 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return false }54
55 // Send deep link to Adjust's servers for attribution.56 // If short branded link, receive long link.57 // Otherwise, receive original link.58 Adjust.processAndResolve(deeplink) { resolvedLink in59 // Handle failure if resolvedLink is nil60 guard let resolvedLink = resolvedLink else { return }61
62 /*63 TODO: Handle the deep link and navigate to the appropriate screen.64
65 resolvedLink format:66
67 example://summer-clothes?promo=beach&adj_t=def45668 - Extract the path and relevant query parameters directly from the URL.69 */70 }71 return true72}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 NSLog(@"[IncomingLink] application:continueUserActivity: url=%@", incomingLink);19
20 // Create deep link object21 ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:incomingLink];22 if (!deeplink) return YES;23
24 // Send deep link to Adjust's servers for attribution.25 // If short branded link, receive long link.26 // Otherwise, receive original link.27 [Adjust processAndResolveDeeplink:deeplink28 withCompletionHandler:^(NSString *resolvedLink) {29 // Handle failure if resolvedLink is nil30 if (!resolvedLink) return;31
32 /*33 TODO: Handle the deep link and navigate to the appropriate screen.34
35 Possible resolvedLink formats:36
37 1. https://brandname.go.link/?adj_t=def456&38 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach39 - Extract and decode the deep link from the 'adj_link' query parameter.40
41 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45642 - Extract the path and relevant query parameters directly from the URL.43 */44 }];45
46 return YES;47}48
49// Receive app scheme deep link when app is installed50// and link opens app from "Not Running",51// Background, or Foreground state.52- (BOOL)application:(UIApplication *)application53 openURL:(NSURL *)incomingLink54 options:55 (NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {56 NSLog(@"[IncomingLink] application:openURL: url=%@", incomingLink);57
58 // Create deep link object59 ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:incomingLink];60 if (!deeplink) return YES;61
62 // Send deep link to Adjust's servers for attribution.63 // If short branded link, receive long link.64 // Otherwise, receive original link.65 [Adjust processAndResolveDeeplink:deeplink66 withCompletionHandler:^(NSString *resolvedLink) {67 // Handle failure if resolvedLink is nil68 if (!resolvedLink) return;69
70 /*71 TODO: Handle the deep link and navigate to the appropriate screen.72
73 resolvedLink format:74
75 example://summer-clothes?promo=beach&adj_t=def45676 - Extract the path and relevant query parameters directly from the URL.77 */78 }];79 return YES;80}SceneDelegate 라이프사이클을 사용하는 UIKit 앱
iOS 다이렉트 딥링킹 메서드를 구현하려면 SceneDelegate를 업데이트하세요.
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 // Create deep link object16 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return }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.processAndResolve(deeplink) { resolvedLink in22 // Handle failure if resolvedLink is nil23 guard let resolvedLink = resolvedLink else { return }24
25 /*26 TODO: Handle the deep link and navigate to the appropriate screen.27
28 Possible resolvedLink formats:29
30 1. https://brandname.go.link/?adj_t=def456&31 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach32 - Extract and decode the deep link from the 'adj_link' query parameter.33
34 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45635 - Extract the path and relevant query parameters directly from the URL.36 */37 }38 return39 }40
41 // Receive incoming app scheme deep link42 guard let incomingLink = connectionOptions.urlContexts.first?.url else { return }43
44 print("[IncomingLink] scene:willConnectToSession:options: url=\(incomingLink.absoluteString)")45
46 // Create deep link object47 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return }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.processAndResolve(deeplink) { resolvedLink in53 // Handle failure if resolvedLink is nil54 guard let resolvedLink = resolvedLink else { return }55
56 /*57 TODO: Handle the deep link and navigate to the appropriate screen.58
59 resolvedLink format:60
61 example://summer-clothes?promo=beach&adj_t=def45662 - Extract the path and relevant query parameters directly from the URL.63 */64 }65}66
67// Receive universal link when app is installed68// and link opens app from Background state.69func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {70 guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,71 let incomingLink = userActivity.webpageURL72 else { return }73
74 print("[IncomingLink] scene:continueUserActivity: url=\(incomingLink.absoluteString)")75
76 // Create deep link object77 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return }78
79 // Send deep link to Adjust's servers for attribution.80 // If short branded link, receive long link.81 // Otherwise, receive original link.82 Adjust.processAndResolve(deeplink) { resolvedLink in83 // Handle failure if resolvedLink is nil84 guard let resolvedLink = resolvedLink else { return }85
86 /*87 TODO: Handle the deep link and navigate to the appropriate screen.88
89 Possible resolvedLink formats:90
91 1. https://brandname.go.link/?adj_t=def456&92 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach93 - Extract and decode the deep link from the 'adj_link' query parameter.94
95 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45696 - Extract the path and relevant query parameters directly from the URL.97 */98 }99}100
101// Receive app scheme deep link when app is installed102// and link opens app from Background103// or Foreground state.104func scene(105 _ scene: UIScene,106 openURLContexts URLContexts: Set<uiopenurlcontext>107) {108 guard let incomingLink = URLContexts.first?.url else { return }109
110 print("[IncomingLink] scene:openURLContexts: url=\(incomingLink.absoluteString)")111
112 // Create deep link object113 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return }114
115 // Send deep link to Adjust's servers for attribution.116 // If short branded link, receive long link.117 // Otherwise, receive original link.118 Adjust.processAndResolve(deeplink) { resolvedLink in119 // Handle failure if resolvedLink is nil120 guard let resolvedLink = resolvedLink else { return }121
122 /*123 TODO: Handle the deep link and navigate to the appropriate screen.124
125 resolvedLink format:126
127 example://summer-clothes?promo=beach&adj_t=def456128 - Extract the path and relevant query parameters directly from the URL.129 */130 }131}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 NSLog(@"[IncomingLink] scene:willConnectToSession:options: url=%@", incomingLink);15
16 // Create deep link object17 ADJDeeplink *deeplink =18 [[ADJDeeplink alloc] initWithDeeplink:incomingLink];19 if (!deeplink) return;20
21 // Send deep link to Adjust's servers for attribution.22 // If short branded link, receive long link.23 // Otherwise, receive original link.24 [Adjust processAndResolveDeeplink:deeplink25 withCompletionHandler:^(NSString *resolvedLink) {26 // Handle failure if resolvedLink is nil27 if (!resolvedLink) return;28
29 /*30 TODO: Handle the deep link and navigate to the appropriate screen.31
32 Possible resolvedLink formats:33
34 1. https://brandname.go.link/?adj_t=def456&35 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach36 - Extract and decode the deep link from the 'adj_link' query parameter.37
38 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45639 - Extract the path and relevant query parameters directly from the URL.40 */41 }];42 return;43 }44 }45
46 // Receive app scheme deep link47 if (connectionOptions.URLContexts.count == 0) return;48
49 UIOpenURLContext *urlContext =50 connectionOptions.URLContexts.allObjects.firstObject;51 NSURL *incomingLink = urlContext.URL;52 NSLog(@"[IncomingLink] scene:willConnectToSession:options: url=%@", incomingLink);53
54 // Create deep link object55 ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:incomingLink];56 if (!deeplink) return;57
58 // Send deep link to Adjust's servers for attribution.59 // If short branded link, receive long link.60 // Otherwise, receive original link.61 [Adjust processAndResolveDeeplink:deeplink62 withCompletionHandler:^(NSString *resolvedLink) {63 // Handle failure if resolvedLink is nil64 if (!resolvedLink) return;65
66 /*67 TODO: Handle the deep link and navigate to the appropriate screen.68
69 resolvedLink format:70
71 example://summer-clothes?promo=beach&adj_t=def45672 - Extract the path and relevant query parameters directly from the URL.73 */74 }];75}76
77// Receive universal link when app is installed78// and link opens app from Background state.79- (void)scene:(UIScene *)scene80 continueUserActivity:(NSUserActivity *)userActivity {81 // Check if it's a web browsing activity82 if (![userActivity.activityType83 isEqualToString:NSUserActivityTypeBrowsingWeb])84 return;85
86 // Check if there's a valid URL87 NSURL *incomingLink = userActivity.webpageURL;88 if (!incomingLink) return;89
90 NSLog(@"[IncomingLink] scene:continueUserActivity: url=%@", incomingLink);91
92 // Create deep link object93 ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:incomingLink];94 if (!deeplink) return;95
96 // Send deep link to Adjust's servers for attribution.97 // If short branded link, receive long link.98 // Otherwise, receive original link.99 [Adjust processAndResolveDeeplink:deeplink100 withCompletionHandler:^(NSString *resolvedLink) {101 // Handle failure if resolvedLink is nil102 if (!resolvedLink) return;103
104 /*105 TODO: Handle the deep link and navigate to the appropriate screen.106
107 Possible resolvedLink formats:108
109 1. https://brandname.go.link/?adj_t=def456&110 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach111 - Extract and decode the deep link from the 'adj_link' query parameter.112
113 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def456114 - Extract the path and relevant query parameters directly from the URL.115 */116 }];117}118
119// Receive app scheme deep link when app is installed120// and link opens app from Background121// or Foreground state.122- (void)scene:(UIScene *)scene123 openURLContexts:(NSSet<uiopenurlcontext *> *)URLContexts {124 // Check if we have any URL contexts125 UIOpenURLContext *urlContext = URLContexts.allObjects.firstObject;126 if (!urlContext) return;127
128 // Check if the URL is valid129 NSURL *incomingLink = urlContext.URL;130 if (!incomingLink) return;131
132 NSLog(@"[IncomingLink] scene:openURLContexts: url=%@", incomingLink);133
134 // Create deep link object135 ADJDeeplink *deeplink = [[ADJDeeplink alloc] initWithDeeplink:incomingLink];136 if (!deeplink) return;137
138 // Send deep link to Adjust's servers for attribution.139 // If short branded link, receive long link.140 // Otherwise, receive original link.141 [Adjust processAndResolveDeeplink:deeplink142 withCompletionHandler:^(NSString *resolvedLink) {143 // Handle failure if resolvedLink is nil144 if (!resolvedLink) return;145
146 /*147 TODO: Handle the deep link and navigate to the appropriate screen.148
149 resolvedLink format:150
151 example://summer-clothes?promo=beach&adj_t=def456152 - Extract the path and relevant query parameters directly from the URL.153 */154 }];155}AppDelegate 라이프사이클을 사용하는 SwiftUI 앱
아직 만들지 않았다면 아래 App.swift 파일 예시와 같이 프로젝트의 기본 디렉터리에 AppDelegate.swift 파일을 만들고 기본 애플리케이션 파일에서 이 파일을 참조하세요. 이는 앱 라이프사이클 이벤트 및 Adjust SDK 연동을 처리하는 데 필요합니다. 또한 앱이 설치되면 유니버설 링크와 앱 스킴 딥링크를 수신하는 onOpenURL SwiftUI 수정자를 구현하세요.
1import AdjustSdk2import 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 // Create deep link object18 guard let deeplink = ADJDeeplink(deeplink: incomingLink) else { return }19
20 // Send deep link to Adjust's servers for attribution.21 // If short branded link, receive long link.22 // Otherwise, receive original link.23 Adjust.processAndResolve(deeplink) { resolvedLink in24 // Handle failure if resolvedLink is nil25 guard let resolvedLink = resolvedLink else { return }26
27 /*28 TODO: Handle the deep link and navigate to the appropriate screen.29
30 Possible resolvedLink formats:31
32 1. https://brandname.go.link/?adj_t=def456&33 adj_link=https%3A%2F%2Fexample.com%2Fsummer-clothes%3Fpromo%3Dbeach34 - Extract and decode the deep link from the 'adj_link' query parameter.35
36 2. https://brandname.go.link/summer-clothes?promo=beach&adj_t=def45637 - Extract the path and relevant query parameters directly from the URL.38
39 3. example://summer-clothes?promo=beach&adj_t=def45640 - Extract the path and relevant query parameters directly from the URL.41 */42 }43 }44 }45 }46}SceneDelegate 라이프사이클을 사용하는 SwiftUI 앱
AppDelegate 라이프사이클을 사용하는 SwiftUI 앱 섹션의 지침을 따르세요. onOpenURL SwiftUI 수정자는 앱이 설치된 상태에서 링크가 백그라운드 또는 포그라운드 상태에서 앱을 열 때 유니버설 링크와 APP SCHEME 딥링크를 수신합니다.
또한 SceneDelegate 라이프사이클을 사용하는 UIKit 앱 섹션에서 scene(_:willConnectTo:options:) 메서드를 구현합니다. 이 메서드는 앱이 설치되어 있고 링크가 ‘실행되지 않는’ 상태에서 앱을 열 때 유니버설 링크와 APP SCHEME 딥링크를 수신합니다.
포그라운드 탐색
프로모션 배너나 제품 추천과 같이 자체 앱 내부에 Adjust 딥링크를 배치한 경우, 해당 링크에 대해 UIApplication.open(_:options:completionHandler:) 또는 SwiftUI의 openURL을 호출하지 마세요. iOS는 앱의 유니버설 링크를 앱 내부에서 라우팅하는 대신 Safari에서 엽니다. 대신, processAndResolve를 통해 링크를 전달한 뒤, 이 페이지에서 설명한 것과 동일한 처리 경로를 사용하여 확인된 딥링크를 라우팅하시기 바랍니다.