호댕의 iOS 개발

[iOS] Deferred Deeplink 적용기 (Appsflyer Onelink) 본문

Software Engineering

[iOS] Deferred Deeplink 적용기 (Appsflyer Onelink)

호르댕댕댕 2023. 9. 5. 21:11

딥링크를 사용하면 앱의 접근성을 올릴 수 있다. 

단순히 사용자가 링크를 눌렀을 때 앱만 실행되고 링크에 해당하는 컨텐츠가 열리지 않는다면...? 해당 링크의 효용성은 아주 떨어지게 된다. 

 

URL Scheme

그래서 가장 초기 형태로 나온 딥링크가 바로 URL Scheme이다. 

 

이는 별다른 제약이 없이 개발자가 원하는 Scheme을 정할 수 있다. 

(Info.Plist에서 URL Types를 지정하면 됨 => {입력한 URL Scheme}:// 이런 식으로 사용 가능)

 

하지만 이를 사용하게 되면 앱이 설치되어 있지 않은 경우 앱스토어로 연결해준다던지 어런 동작은 불가능하다. 

그리고 Scheme은 Unique하지 않기 때문에 같은 Scheme이 존재할 수도 있다.

 

Universal Links

이런 단점들을 해소하기 위해 등장한 것이 바로 Universal Links이다. 

https://ho8487.tistory.com/101

 

[iOS] Universal Links에 대해 알아보자

이전 푸쉬 알림을 진행하며 원링크의 푸쉬 알림에 유니버셜 링크를 전달받아 이를 통해 앱의 특정 컨텐츠를 여는 작업을 했었다. 푸쉬 알림을 받을 때의 처리는 직접 했지만 유니버셜 링크에 대

ho8487.tistory.com

(자세한 내용은 위 포스팅에서 써놨어요!)

 

이를 사용하면 앱이 설치되어 있는 경우 해당 링크에 해당하는 화면으로 이동하게 되며 앱이 설치되어 있지 않다면 웹 URL로 인식되어 웹 링크를 열도록 시도하며 이를 통해 앱스토어로 이동시킬 수도 있다. 

 

하지만...

 

여기도 아쉬운 점은 존재한다. 

바로 앱이 설치되어 있지 않은 경우, 설치 후 앱에 들어가면 원래 링크에서 랜딩하려고 했던 뷰로 가지 못하는 것이다. 

 

그래서 바로 Deferred Deeplink가 존재한다!!!

 

Deferred Deeplink

문자 그대로 해석하자면 연기된 딥링크라는 것이다. 

 

우리가 Universal Links를 사용할 때 아쉬웠던 점이 바로 앱이 설치 되어 있지 않은 경우 링크를 누르면 앱스토어로 연결시켜 앱을 설치하도록 유도까진 할 수 있지만, 설치한 후 원래 랜딩하려 했던 뷰로 넘길 수 없다는 점이었다. 

 

하지만 이를 사용하면 

  • 앱이 설치 되었을 때 : 앱이 실행되며 링크에 해당하는 뷰로 이동
  • 앱이 설치 되어있지 않은 경우 : 랜딩해야 하는 뷰에 대한 정보를 다른 곳에 저장을 해놓은 뒤 앱이 설치되고 실행했을 때 이를 불러와 링크에 해당하는 뷰로 이동

 

이렇게 앱에 대한 접근성을 조금 더 높일 수 있다. 

 

애플에서도 이런 기능을 지원해주면 좋겠지만 😭 아직은 없다... ㅎㅎ

 

여기서 중요한 부분은 바로 랜딩해야 하는 뷰에 대한 정보를 다른 곳에 저장을 해놓은 뒤 앱이 설치되고 다시 전달하는 기능이다. 

물론 이를 직접 구현할 수도 있겠지만 그러기 위해선 또 백엔드 리소스도 필요할 것이고, 해당 사용자인지 파악하기 위해 UDID 같은 기기 고유 값을 서버로 전달해야 하니... 이것도 찝찝하다. 

 

그리고 iOS 14 이후로는 Apple에서 App Tracking Transparency (ATT) 기능을 도입해서 개인정보 보호가 좀 더 강화되었고 올해 WWDC에선 이런 부분이 좀 더 강화된다고 발표를 했다. 

 

그래서 이런 기능을 제공하는 써드파티 툴들이 존재한다. 

 

  • Appsflyer One Link
  • Firebase Dynamic link
  • Airbridge
  • Adjust

이외에도 다른 툴들도 존재했다. 

 

하지만 현재 사용 중이지 않은 Airbridge와 Adjust를 도입하기엔 기능의 효용성과 가져올 이익에 비해 추가적인 비용을 써야한다는 점에서 제외되었다. 

 

그리고 Firebase Dynamic Link는...

25년 8월 25일에 지원이 중단될 예정이라 사용 중이지 않은 프로젝트에선 사용하지 말라고 하고 있다.. ㅎㅎ

그래서 내가 선택한 방법은 Appsflyer였다. 

 

https://dev.appsflyer.com/hc/docs/dl_ios_unified_deep_linking

 

iOS Unified Deep Linking

At a glance: Unified deep linking (UDL) enables you to send new and existing users to a specific in-app activity (for example, a specific page in the app) as soon as the app is opened.📘UDL privacy protectionFor new users, the UDL method only returns par

dev.appsflyer.com

이를 지원하기 위해 추가해야 하는 코드 자체는 간단했다. 

 

AppsflyerLib에서 제공하는 Delegate들을 AppDelegate나 SceneDelegate에 채택해주고 딥링크를 통해 앱을 실행할 때 호출되는 함수를 정의해주기만 하면 된다. 

 

이 부분은 코드 가이드도 잘 되어 있어서 쉽게 할 수 있었다. 

 

하지만 문제는... 엄청 다양한 각각의 상세 화면으로 이동시킬 링크가 있어야 했는데 이런 링크를 어떻게 생성하고 관리하는 지였다. 

딥링크 관련 메뉴를 봤을 때 Bulk Links라는 메뉴가 있어서 진짜 많은 양의 링크를 만들 수 있게 되어 있었다. 

그래서 상세화면마다 생성해야 하나 라는 고민이 깊어져갔다... 

 

그리고 링크를 각각 전부 만들어 놓는다 하더라도 이 링크를 어떻게 상세 화면에서 알 수 있도록 할까도 고민이었다. 

만약 상세 화면에 대한 데이터를 서버에서 받아올 때 이 링크를 받아오면 구현은 가능하겠지만 그러면 또 서버 작업이 필수였고, 상세 화면의 데이터에도 전부 링크를 붙이고 앞으로 추가되는 데이터에도 링크를 추가로 생성해 붙여줘야 했다. 

 

물론 이 방법이 정석적인 방법일 수 있겠으나, 현재 해당 작업이 가져오는 효용 가치에 대비해서 추가로 들어가야 하는 리소스와 유지보수 비용이 너무 크다는 생각이 들었다. 

 

안드로이드 개발자 분과도 이야기를 나눴지만 동일한 의견이셨다. 

 

그럼 코드에서 랜딩할 뷰에 대한 정보를 넣어줄 수는 없을까...?

이에 대해 진짜 하루 종일 고민하고 또 고민했다. 

 

공식문서를 2번 읽어봤지만... 관련 내용은 찾을 수 없었다. 

 

https://support.appsflyer.com/hc/ko/articles/207447163

아니 그런데 위 링크에서 각 파라미터에 대한 설명을 하고 있는데 눈길을 끄는 파라미터가 있었다.

이거 내가 딱 필요한 건데... 그런데 어떻게 이걸 코드에서 적용할 수 있을까...

 

Onelink Management 쪽에서 미리 이 값을 넣을 수는 있었지만 이걸 나중에 넣는 방법은 생각나지 않았다. 

 

그러다가... 일단 기본적으로 OneLink는 축약한 Short URL 형태로 나오게 되는데 이를 Long URL로 바꿔보니...!

 

지금까지 적용한 값들이 쿼리 파라미터 형태로 되어 있었다. 

아 그러면 혹시 임의로 쿼리 파라미터를 넣어주면 안될까?

 

Key값은 deep_link_value와 deep_link_sub1로! Key 값에 대한 설명을 보더라도 해당 값을 넣었을 때 적합하다고 보여졌다.

{생성된 원링크}?deep_link_value={랜딩해야 할 뷰}&deep_link_sub1={추가 정보}

 

그래서 넣고 AppsFlyerLib의 DeepLinkDelegate에서 didResolveDeeplink 함수에서 들어오는 result 값을 보니!

extension AppDelegate: DeepLinkDelegate {
    func didResolveDeepLink(_ result: DeepLinkResult) {
    }
}

result.deeplink에 내가 쿼리 파라미터로 넣었던 값이 deep_link_value와 deep_link_sub1 키에 value로 잘 들어가 있었다!! 

물론 이렇게 하면 단점은 링크가 더러워진다. 

(링크를 축약하는 다른 API를 사용할 수도 있겠다)

 

그리고 기본적으로 fallback으로 제대로 딥링크를 통해 연결이 안됐을 때 가게 되는 콘텐츠의 이미지가 링크를 공유했을 때 보이게 된다.

그래도 리소스를 최소화하면서 다양한 콘텐츠로 바로 이동할 수 있는 방법을 찾긴 해서 다행이다... ㅎㅎㅎ

이 문제는 좀 더 디깅하면서 해결해 봐야겠다. 

Comments