앱이 설치된 사용자가 Adjust 링크를 클릭하면 다이렉트 딥링킹을 통해 앱 내의 특정 콘텐츠로 바로 이동할 수 있습니다.
설정
iOS는 앱 구현에 따라 다이렉트 딥링크를 수신하는 몇 가지 메서드를 제공합니다.
이러한 메서드에 따라 다음 메서드 중 하나를 사용하여 Adjust SDK에 딥링크를 전달할 수 있습니다.
딥링크 처리 및 확인(권장)
processDeeplink(_:completionHandler:) 메서드를 사용하여 다음 작업을 수행합니다.
- 딥링크 클릭에서 어트리뷰션 기록
- 짧은 브랜드 링크를 해당 긴 브랜드 링크로 변환
- 다른 모든 링크를 그대로 전달
앱은 해결된 링크를 분석하여 적절한 화면으로 이동함으로써 처리할 수 있습니다. Adjust의 긴 브랜드 링크, 기타 유니버설 링크, 앱 스킴 딥링크를 포함한 모든 딥링크에 이 메서드를 사용할 수 있습니다.
+ (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 앱
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 // 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 앱
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 // 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 앱
아직 만들지 않았다면 아래 App.swift 파일 예시와 같이 프로젝트의 기본 디렉터리에 AppDelegate.swift 파일을 만들고 기본 애플리케이션 파일에서 이 파일을 참조하세요. 이는 앱 라이프사이클 이벤트 및 Adjust SDK 연동을 처리하는 데 필요합니다. 또한 앱이 설치되면 유니버설 링크와 앱 스킴 딥링크를 수신하는 onOpenURL SwiftUI 수정자를 구현하세요.
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 수정자는 앱이 설치된 상태에서 링크가 백그라운드 또는 포그라운드 상태에서 앱을 열 때 유니버설 링크와 APP SCHEME 딥링크를 수신합니다.
또한 SceneDelegate 라이프사이클을 사용하는 UIKit 앱 섹션에서 scene(_:willConnectTo:options:) 메서드를 구현합니다. 이 메서드는 앱이 설치되어 있고 링크가 ‘실행되지 않는’ 상태에서 앱을 열 때 유니버설 링크와 APP SCHEME 딥링크를 수신합니다.
포그라운드 탐색
프로모션 배너나 제품 추천과 같이 자체 앱 내부에 Adjust 딥링크를 배치한 경우, 해당 링크에 대해 UIApplication.open(_:options:completionHandler:) 또는 SwiftUI의 openURL을 호출하지 마세요. iOS는 앱의 유니버설 링크를 앱 내부에서 라우팅하는 대신 Safari에서 엽니다. 대신, processDeeplink를 통해 링크를 전달한 뒤, 이 페이지에서 설명한 것과 동일한 처리 경로를 사용하여 확인된 딥링크를 라우팅하시기 바랍니다.