Android DeepLink와 AppLink의 이해

2020. 9. 25. 13:22

Android DeepLink와 AppLink의 이해

 

App Deep Link

 

URL Scheme, Deep Link 메커니즘은 Android 1.0에서부터 제공되었다. 개발자가 일단 앱을 설치하면 특정 장치에 대한 앱의 URI(Uniform Resource Indentifier)를 운영체제에 등록할 수 있다. URI는 HTTP, market 혹은 myapp과 같은 특수 문자를 포함하지 않는 어떤 문자열로 될 수 있고, 한번 등록하면, 끝에 ://를 붙이고(예를 들면, market://)  링크를 클릭하기만 하면 Google Play 혹은 스토어 앱이 구동된다. 이와 같이 사용자들에게 앱을 직접적으로 구동할 수 있게 해 주는 것이 딥 링크(Deep Link)이다.

 

  • 사용자를 앱 특정 Contents로 바로 연결하는 URL
  • Intent filter를 추가하고 수신 Intent에서 데이터를 추출하여 딥 링크를 설정
  • 다른 앱에서 동일한 Intent를 처리할 수 있다면 사용자는 개발자의 앱으로 바로 이동하지 않음.

 

안드로이드 URI Scheme

 

Intent filter를 통해 URI에 응답할 Activity를 매니페스트 파일에 등록한다. 이를 사용하기 위해서는 당연히 앱이 설치되어 있어야한다. 앱이 설치되어 있지 않다면, Page Not Found 에러 혹은 아무런 동작을 하지 않을 것이다.

 

    <activity
        android:name="com.example.android.MyAppActivity"
        android:label="@string/title_myapp" >
        <intent-filter android:label="@string/filter_view_example_myapp">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "example://myapp” -->
            <data android:scheme="example" android:host="myapp" />
        </intent-filter>
    </activity>
   

 

앱이 최초 설치될 때 Intent-filter를 통해 앱이 수신가능한 딥 링크를 운영체제에 등록을 할 수 있고, 해당 URI Scheme의 이벤트가 발생하면 이를 해당 앱을 전달하여 구동된다. 하지만, myroute.co.kr 같은 도메인과는 다르게 URI Scheme에는 유니크한 제한이 없기 때문에 여러 앱에서 같은 URI Scheme을 사용하기도 한다. 예를 들어, market:// 스킴은 Google Play에서도 정의하고 있지만 Galaxy Store, 원스토어에서도 동일한 스킴을 정의해 두었다. 이렇게 동일한 URI Scheme이 있을 경우에는 Chooser를 통해 구동할 앱을 결정한다.

 

번외로, 예전에 원스토어에서 market:// 스킴을 등록했다가 다른 회사들의 요청 의해 철회된 적이 있다. 하지만 최근 Galaxy Store가 이를 등록함으로서 원스토어에서도 다시 정의한 것으로 보인다. 그리고 이는 구글 정책상 open framework으로서 앱스토어로서 동일하게 구현할 수 있게 하기 위해서이다. 

 

 

 

수신되는 Intent에서 데이터 읽기

 

앱이 Intent filter를 통해서 구동되면 Intent에서 제공하는 데이터를 사용하여 렌더링해야하는 경우들이 종종 발생한다. 이를 위해서 getData() 및 getAction() 메소드를 호출하여 수진 Intent와 연결된 데이터와 작업을 가져올 수 있다. 액티비티 생명주기 동안에 이러한 메소드를 통해서 언제든지 확인가능하며, 일반적으로 onCreate()나 onStart()와 같은 초기 콜백에서 호출한다.

 

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent intent = getIntent();
        String action = intent.getAction();
        Uri data = intent.getData();
        
		...
    }
    

 

 

Deferred Deep Linking

 

앞에서 언급 했듯이 딥 링크는 특정 페이지로 도달 할 수 있도록 하는 링크를 의미한다. 하지만 앱이 설치되어 있지 않다면 이는 무용지물이다. 조금 더 구체적인 예를 들어보자면, 회사에서는 많은 돈을 사용해서 포털에 광고를 하고 이 광고배너를 클릭시 모바일 앱을 구동하고 싶어한다. 그리고 특정 프로모션 페이지로 이동하기를 원할 것이다. 하지만 고객의 핸드폰에는 회사의 앱이 설치되어 있을 수도 있고 그렇지 않을 수도 있다.

 

앱을 미설치한 고객의 경우 앱 스토어로 이동하면서 기존에 있던 Deep Link의 정보를 유실하게 되는 경우가 있다. 이를 해결하고자 등장한 개념이 디퍼드 딥 링크로 기존 고객은 앱 내 특정 페이지로 바로 이동하고, 미설치 고객들은 앱 스토어로 이동 후 고객이 설치 및 실행하면 앱 내 특정 페이지로 이동하는 것이다.

 

 

 

위에서 언급한 것처럼 외부에 광고 배너를 노출했다면, 우선적으로 회사의 웹 페이지의 랜딩페이지로 이동한다.

그리고 꼼수(?)를 통해서, 바로 app scheme을 실행시키고, 반응이 없을 것을 대비하여 약간의 Delay를 통해 앱 스토어로 이동할 수 있도록 한다.

// Link to landing page in your company
https://link.yourcompany.com/banner/front_url={https://encodedUrl}

// fallback url for market
market://details?id=com.yourcompany.mobile
   &url={encoded scheme URI. e.g myapp://list?key1=value1&key2=value2}
   &referrer={encoded DATA. e.g key1=value1&key2=value2}
   
<script type="text/javascript">
window.onload = function() {
	var now = new Date().getTime();

    setTimeout(function() {
    	if(new Date().getTime() - now < 1000) {
        	// Link to the App Store should go here -- only fires if deep link fails                
        	location.href = "app store url";
        }
    }, 500);
    
    setTimeout(function() {
        // Link to the App Store should go here -- only fires if deep link fails                
        location.href = "app scheme";
    }, 100);
};
</script>

 

 

Deep Link 테스트

 

Android Debug Bridge(ADB)를 활동 관리자(am) 도구와 함께 사용하여 딥 링크용으로 지정한 Intent filter URI가 올바른 앱 활동으로 확인되는지 테스트 할 수 있다.

 

$ adb shell am start -W -a android.intent.action.VIEW -d <URI> <PACKAGE>
    
$ adb shell am start -W -a android.intent.action.VIEW -d "example://myapp" com.example.android

 

Google Play에서의 install referrer 역시 ADB를 통해서 테스트 할 수 있다.

 

$ adb shell am broadcast -a com.android.vending.INSTALL_REFERRER
	-n com.yourcompany.mobile/{com.yourcompany.mobile.install}.ReferrerReceiver
    -es referrer "key1=value1"

 

 

URI Scheme의 한계

 

URI Scheme는 제약없이 설정할 수 있기 때문에 앱 별로 고유한 딥 링크를 점유하는 것이 불가능하다. 위에서 언급한 것과 같이 다른 앱에서 Scheme값을 중복한다면 다른 앱에서 하이재킹(hijacking)될 수도 있다. 이러한 보안 문제로 iOS에서는 9.1 버전 이후로는 URI Scheme에 대한 추가 개발하지 않겠다고 공지했고, 몇몇 웹 브라우저와 앱에서는 URI Scheme에 대한 경고 메세지를 띄우거나 Scheme이 동작하지 않도록 하였다.

 

 

App Link(Dynamic Link)와 Universal Link

 

URI Scheme이 가진 문제점을 해결하기 위해 2015년 하반기에 Android와 iOS 플랫폼은 각각 새로운 딥 링크를 개발하여 발표하였고, iOS는 Universal Link, Android는 App Link를 발표했다. 구동되는 환경은 다르지만, 개념적으로는 비슷한 형태의 딥 링크이다.

 

이는 도메인의 고유성과 HTTPS의 SSL(secure sockets layer) 인증서를 이용해 딥링크를 안전한 자원으로 관리, 사용하여 기존에 존재했던 보안 문제를 해결하고자 했다.

 

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "myapp",
    "package_name": "com.yourcompany.mobile",
    "sha256_cert_fingerprints": ["XX:YY:ZZ:..."]
  }
}]
<intent-filter>
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <action android:name="android.intent.action.VIEW" />
    <data
      android:pathPattern="/document/.*\\"
      android:host="www.yourcompany.com"
      android:scheme="http" />
    <data
      android:path="/category"
      android:host="www.yourcompany.com"
      android:scheme="http" />
</intent-filter>

 

 

App Link의 한계 

 

App Link는 사용자 클릭이 트리거(trigger)되었을 때만 동작합니다. 예를 들어 jQuery 이벤트인 document ready에서 링크를 실행했을 때는 앱이 설치되어 있음에도 불구하고 fallback URL로 동작합니다. 또한 특정 앱에서 동작하지 않도록 막은 경우도 있습니다. 대표적으로 Pinterest, WeChat, Facebook Messenger, Telegram 등의 앱에서는 지원되지 않습니다. 마지막으로 iOS는 9.2 미만, Android는 마시멜로(6.0) 미만 버전에서는 사용할 수 없습니다. 이런 이유 때문에 Universal Link와 App Link가 실행되지 않는 상황에 대응하기 위해 URL schemes와 복합적으로 사용해야 합니다.

 

Android 6.0(마시멜로 API 23)이상의 Android 앱 링크를 사용하면, 특정 유형의 링크에 적용되는 기본 핸들러로 앱 자체를 지정가능하다. 하지만, Android 6.0 미만 버전에서 사용할 수 없고, Pinterest, Facebook Messenger 등 특정 앱에서는 동작하지 않도록 막는 경우도 있다. 그리고 Intent Scheme 역시 Google Chrome에서만 사용할 수 있는 기능이기 때문에 여전히 문제점들이 있다.

 

 

 

 

복합적인 Deep Link/App Link의 구현

 

Deep Link와 App Link에는 여전히 문제점을 가지고 있다. 결국 이를 해결하기 위해서는 유저의 상태를 보고 이를 해결해야한다. App Link가 동작하는지, 앱이 설치되어 있는지를 단계적으로 확인하는 모습이 필요하다.

 

 

 

 

 

 

 

참고문헌

 

developer.android.com/training/app-links

shinjekim.github.io/android/2019/08/07/Android-DeepLink/

engineering.linecorp.com/ko/blog/how-to-use-deeplink-in-trackit/