iOS 통합 딥링킹

요약: 통합 딥링킹(UDL: Unified Deep Linking)을 사용하면 앱을 열자마자 앱의 특정 인앱 액티비티(예: 앱의 특정 페이지)에 새 사용자 및 기존 사용자를 보낼 수 있습니다.

📘

UDL 프라이버시 보호

For new users, the UDL method only returns parameters relevant to deferred deep linking: deep_link_value and deep_link_sub1-10. If you try to get any other parameters (media_source, campaign, af_sub1-5, 등), null 값을 반환합니다.

단계별 예시

순서

iOS UDL flow!

순서는 다음과 같이 작동합니다.

  1. 사용자가 원링크 링크를 클릭합니다.
    • 사용자가 앱을 설치한 경우, 유니버설 링크나 URI 스킴이 앱을 엽니다.
    • 사용자가 앱을 설치하지 않은 경우, 앱 스토어로 리디렉션되고, 다운로드 후에는 사용자가 앱을 엽니다.
  2. 열린 앱이 앱스플라이어 SDK를 트리거합니다.
  3. AppsFlyer SDK는 UDL API를 실행합니다.
  4. UDL API는 AppsFlyer 서버에서 원링크 데이터를 가져옵니다.
  5. The UDL API calls back the didResolveDeepLink() in the DeepLinkDelegate.
  6. The didResolveDeepLink() method gets a DeepLinkResult object.
  7. The DeepLinkResult object includes:
    • 상태(찾음/찾을 수 없음/오류)
    • A DeepLink object that carries the deep_link_value and deep_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.

선행 조건

  • UDL에는 AppsFlyer 안드로이드 SDK V6.1 이상이 필요합니다.

계획

원링크를 설정할 때, 마케터는 파라미터를 사용하여 링크를 생성하고, 개발자는 수신된 값을 기반으로 앱의 작동을 맞춤 설정합니다. 앱에서 파라미터를 올바르게 처리하고 인앱 라우팅 및 링크에서 데이터를 맞춤 설정하는 것은 개발자의 책임입니다.

원링크를 계획하는 방법:

  1. URL을 클릭할 때 사용자에게 바람직한 동작과 개인적 경험을 마케터로부터 얻습니다.
  2. 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 of deep_link_value can be apples.
    • 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 of deep_link_sub1 can be 10.

구현하기

선택한 파라미터 및 값을 기반으로 UDL API 로직을 구현합니다.

  1. Assign the AppDelegate using self to AppsFlyerLib.shared().deepLinkDelegate.
  2. 다음을 허용하는 애플리케이션 기능을 구현합니다:
    • 다음으로 유니버설 링크 지원 continue.
    • 다음을 통한 URI 스키마 지원 handleOpen.
  3. Create DeepLinkDelegate as an extension of AppDelegate.
  4. Add application functions to support Universal Links and URI schemes.
  5. In DeepLinkDelegate, make sure you override the callback function, didResolveDeepLink().
    didResolveDeepLink() accepts a DeepLinkResult object as an argument.
  6. Use DeepLinkResult.status to query whether the deep linking match is found.
  7. For when the status is an error, call DeepLinkResult.error and run your error flow.
  8. For when the status is found, use DeepLinkResult.deepLink to retrieve the DeepLink object.
    The DeepLink object contains the deep linking information arranged in public variables to retrieve the values from well-known OneLink keys, for example, DeepLink.deeplinkValue for deep_link_value.
  9. Use deepLinkObj.clickEvent["deep_link_sub1"] to retrieve deep_link_sub1. Do the same for deep_link_sub2-10 parameters, changing the string value as required.
  10. Once deep_link_value and deep_link_sub1-10 are retrieved, pass them to an in-app router and use them to personalize the user experience.

Supporting legacy OneLink links

레거시 OneLink 링크는 통합 딥링킹에 권장되는 파라미터를 포함하지 않는 링크입니다. deep_link_value and deep_link_sub1-10.
일반적으로 이러한 링크는 레거시 메소드에서 UDL로 마이그레이션할 때 필드에 이미 존재합니다.
레거시 링크를 사용하는 신규 사용자는 onConversionDataSuccess 확장된 디퍼드 딥링킹의 맥락에서.
UDL은 기존 사용자에 대한 딥링킹을 처리합니다. 레거시 파라미터에 대한 UDL 콜백 지원을 didResolveDeepLink 추가하는 것이 좋습니다.
Swift 코드 예시

Code example

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
  ...
  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)")
    }
}

⇲ Github 링크: Swift

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

디퍼드 딥링킹 테스트

Before you begin

  • 완전한 UDL 연동.
  • 테스트 기기 등록.
  • 앱에서 디버그 모드 활성화를 수행합니다.
  • 앱이 기기에 설치되어 있지 않은지 확인합니다.
  • 마케터에게 원링크 템플릿 요청
    • 다음과 유사할 것입니다. https://onelink-basic-app.onelink.me/H5hv.
    • 이 예시에서는 원링크 하위 도메인과 onelink-basic-app.onelink.me 원링크 템플릿 ID를 사용합니다 H5hv.

The test link

기존 OneLink 링크를 사용하거나 마케터에게 테스트할 새 링크를 만들도록 요청할 수 있습니다. 짧은 원링크 URL과 긴 원링크 URL을 모두 사용할 수 있습니다.

기존 링크에 임시 파라미터 추가하기

  • 도메인과 링크의 원링크 템플릿만 사용하십시오. 예시: https://onelink-basic-app.onelink.me/H5hv.
  • 애플리케이션에서 예상한 대로 원링크 파라미터 deep_link_value and deep_link_sub1-10 애플리케이션에서 예상한 대로. 파라미터는 쿼리 파라미터로 추가해야 합니다.
    • 예: https://onelink-basic-app.onelink.me/H5hv?deep_link_value=apples&deep_link_sub1=23

Perform the test

  1. 기기에서 링크를 클릭합니다.
  2. 원링크는 링크 설정에 따라 사용자를 앱 스토어 또는 웹사이트로 리디렉션합니다.
  3. 애플리케이션을 인스톨합니다.

    중요 정보

    • 이 애플리케이션아직 개발 중이고 아직 스토어에 업로드되지 않은 경우 다음 이미지가 표시됩니다.
      drawing
    • Xcode에서 애플리케이션을 설치합니다.
  4. UDL은 디퍼드 딥링킹을 검색하고 인스톨을 클릭과 일치시키며 원링크 파라미터를 didResolveDeepLink 검색합니다.

Expected logs results

📘

다음 로그는 오직 디버그 모드가 활성화된 경우에만 사용할 수 있습니다.

  • SDK가 초기화되었습니다.
    [AppsFlyerSDK] [com.apple.main-thread] AppsFlyer SDK version 6.6.0 started build
    
  • UDL API가 시작됩니다.
    D/AppsFlyer_6.9.0: [DDL] start
    
  • UDL은 앱스플라이어에 쿼리를 보내 이 인스톨과 매치되는 항목을 쿼리합니다.
    [AppsFlyerSDK] [com.appsflyer.serial] [DDL] URL: https://dlsdk.appsflyer.com/v1.0/ios/id1512793879?sdk_version=6.6&af_sig=efcecc2bc95a0862ceaa7b62fa8e98ae1e3e022XXXXXXXXXXXXXXXX
    
  • UDL이 응답을 받고 호출 didResolveDeepLink 콜백 status=FOUND 및 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":""}
    

딥링킹 테스트(유니버설 링크)

Before you begin

Create the test link

디퍼드 딥링킹과 동일한 방법을 사용합니다.

Perform the test

  1. 기기에서 링크를 클릭합니다.
  2. UDL은 유니버설 링크를 감지하고 다음에 대한 원링크 파라미터를 검색합니다 didResolveDeepLink 검색합니다.

Expected logs results

📘

다음 로그는 오직 디버그 모드가 활성화된 경우에만 사용할 수 있습니다.

  • 링크가 원링크 단축링크인 경우(예: 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는 다음을 호출 didResolveDeepLink 콜백 status=FOUND 및 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}