[DeepLink/AppLink] 링크를 통해 앱 화면 열기

2 분 소요

👩🏻‍💻 딥링크?

웹사이트를 하나의 주소가 단 하나의 웹사이트만을 표시하는 것을 알 수 있다. 이렇게 하나의 주소가 앱 상의 하나의 화면으로 향하게 하는 기능이 딥링크이다.

👩🏻‍💻 딥링크의 세가지 방식

  1. URL 스킴 방식
    • url scheme
    • intent-filterurl scheme을 설정하여 사용하는 가장 기본적인 딥링크 방식이다.
  2. 도메인 주소 방식
    • AppLink
    • domain 주소를 활용한 딥링크 방식이다.
    • Android 제공 - UniversalLink (해당 글에서는 다루지 않습니다.)
    • domain 주소를 활용한 딥링크 방식이다.
    • IOS 제공

우선 이번 시간에는 URL 스킴의 사용 방법에 대해 다루고 이러한 방식의 문제점에 대해 정리해보고자 한다.

👩🏻‍💻 Url scheme

intent-filter를 이용하는 경우

uri 패턴 형식: {scheme}://{path}?{query}={value}

        <activity
            android:name=".home.MainActivity"
            android:screenOrientation="sensorLandscape"
            android:windowSoftInputMode="adjustPan"
            android:launchMode="singleInstance"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data android:scheme="app:" />
                <data android:host="www.cafepos.com" />
                <data android:pathPattern="/preorder" />
            </intent-filter>
        </activity>

이렇게 AndroidManifest.xml에 intent-filter를 설정해 간단히 url 스킴을 활용할 수 있다. 앱링크를 만들 때도 위와 같이 intent-filter를 설정해줘야 하는데 그때는 schemehttp로 설정하면 된다.

이렇게 정의한 url scheme을 사용할 때는

            val preorderId = intent.getIntExtra("preorderId", -1)
            val uri = Uri.parse("app://www.cafepos.com/preorder?preorderId=$preorderId")
            val intent = Intent().also {
                it.data = uri
            }
            startActivity(intent)

intent에 data를 통해 넘겨줄 수 있으며 넘겨진 데이터를 다음과 같이 처리할 수 있다.

    private fun handleIntent(intent: Intent) {
        val deepLinkData: Uri? = intent.data
        deepLinkData?.let {
            val preorderId = it.getQueryParameter("preorderId")?.toInt()
            checkPreorderAlarm(preorderId)
        }
    }

이렇게 intent.data에 url를 설정하면 해당 url에 대해 딥링크가 적용된다고 한다. 이렇게 intent-filter를 활용한 deepLink를 적용할 경우, 특정 fragment로 이동할 때 무조건 해당 fragment를 포함하는 activity를 거쳐야 한다는 번거로움이 존재한다.

따라서 특정 fragment에 직접 딥링크를 적용하는 방식이 바로 navigation-graph를 활용한 딥링크 방식이다.

해당 과정은 공식문서암시적 딥링크 만들기 부분을 참고했다.

  1. 우선 navigation graph에 딥링크를 추가한다.
       <fragment
           android:id="@+id/fragment_preorder"
           android:name="org.swm.att.home.preorder.PreorderFragment"
           android:label="@string/fragment_preorder"
           tools:layout="@layout/fragment_preorder">
           <argument
               android:name="preorderId"
               android:defaultValue="-1"
               app:argType="integer" />
           <deepLink
               android:id="@+id/deepLink1"
               app:uri="www.cafepos.com/preorder/{preorderId}" />
       </fragment>
    

    -> AndroidStudio interface를 활용해 쉽게 딥링크를 추가할 수 있다.

  2. 딥링크가 정의된 navigation graph를 manifest에 설정해준다.
     <fragment
         android:id="@+id/fragment_preorder"
         android:name="org.swm.att.home.preorder.PreorderFragment"
         android:label="@string/fragment_preorder"
         tools:layout="@layout/fragment_preorder">
         <argument
             android:name="preorderId"
             android:defaultValue="-1"
             app:argType="integer" />
         <deepLink
             android:id="@+id/deepLink4"
             app:uri="www.cafepos.com/preorder/{preorderId}" />
     </fragment>
    

    여기서 {preorderId}를 통해 전달할 값을 설정할 수 있다.

  3. 본격 딥링크 사용!

앱 내부에서 uri를 실행할 거라면 navController를 통해 uri를 전달해줌으로써 딥링크를 실행할 수 있다.

  val uri = Uri.parse("https://www.cafepos.com/preorder/$preorderId")
  findNavController().navigate(uri)

그리고 link를 통해 전달된 preorderId를 다음과 같이 뽑아 사용할 수 있다.

     override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        Log.d("MainActivity", "onNewIntent: ${intent?.data?.lastPathSegment}")
        Log.d("MainActivity", "onNewIntent: ${intent?.data?.getQueryParameter("preorderId")}") // 'preorder?preorderId=$preorderId'일 경우
        navController.handleDeepLink(intent ?: return)
    }

👩🏻‍💻 url을 통한 딥링크의 문제점

그렇다면 이렇게 url을 활용한 deeplink를 사용할 떄 문제점이 뭐길래 도메인 주소를 활용한 딥링크가 나왔을까?

  1. url을 원하는 방식으로 구성할 수 있다.
    • 앱 스킴 값이 서로 중복되는 경우가 발생할 수 있다. 앱 개발자들은 앱 스킴값이 고유한 값인지 확인할 방법이 없다. 따라서 다른 앱이 고의적으로 특정 앱의 앱 스킴을 사용해도 해당 앱이 열리도록 해도 이를 막을 방법이 없다.
  2. 앱이 설치되어 있을 때만 실행할 수 있다.

따라서 이를 해결하기 위해 각자 고유한 값을 가진 도메인 주소를 활용한 앱링크/유니버셜링크가 등장하게 되었다.

👩🏻‍💻 참고

댓글남기기