딥링크(Deep Link) 구현하기

조관희·2025년 5월 18일
2

안녕하세요.

딥링크는 무엇이고, 안드로이드에서는 어떻게 딥링크를 구현할 수 있을 지에 대해서 설명해보려고 합니다.

우선 딥링크란 무엇일까요?

딥링크는 사용자가 특정 링크를 클릭하면 특정 앱으로 이동하거나 사용자에게 액션을 유도하는 링크를 딥링크라고 합니다.

카카오톡으로 누군가를 독려하는 메시지를 보냈다고 가정할게요.

독려 메시지에 [참여하기]라는 버튼을 클릭했을 때, 어디로 이동하셨으면 좋을 것 같나요?

앱이 존재하면 앱으로 이동하고, 앱이 존재하지 않다면 구글 플레이 스토어로 이동하기를 기대할 수 있습니다.

이처럼 딥링크를 유용하게 사용하면 마케팅에서 좋은 전략이 될 수 있습니다.

그렇다면 딥링크는 어떻게 구성되나요?

링크라고 한다면 다들 아시는 웹 사이트의 주소를 떠올릴겁니다.

딥링크도 그 주소의 구성과 유사합니다.

흔히 사용되는 구성은 위의 그림과 같습니다.

이렇게 구성을 한 이유는 여러가지 있습니다.

  • 웹 주소와의 유사함을 가지기 위함입니다.
    • scheme://host 는 https://host 와 구조가 동일합니다.
  • URI 설계 원칙인 RFC-3986 를 따릅니다.
    • scheme:// [userinfo@] host[:port][/path][?query][#fragment] 의 구조를 가집니다.
    • “슬래시 구분자(//)는 계층 관계를 나타내는데 사용한다”, “하이픈(-)은 URI 가독성을 높이는데 사용한다” 등 여러 규칙이 존재합니다.

여러가지 이유가 더 있겠지만, 위에서 말한 이유로 위 구조를 따르게 하면 딥링크 사용 시 Android, iOS, 웹 등 다양한 플랫폼에서 동일한 규칙으로 파싱할 수 있습니다.

하지만, 여기에서도 문제점이 존재합니다.

만약 안드로이드 OS에서 같은 스킴(Scheme)을 가진 앱이 여러개 존재한다면, 무슨 앱을 열어야 하는 지 알 수 없습니다.

그래서 앱을 선택할 수 있는 UI가 나타납니다.

(iOS에서는 해결할 수 있는 방법이 없다고 합니다.)

iOS에서는 해결할 수 없고, Android 에서 특정 앱을 열 수 없다니... 그렇다면 다른 방법이 없을까요?

다른 방법이 존재합니다.

  • Android - App Link
  • iOS - Universal Link

를 사용하면 됩니다.

App Link와 Universal Link는 2015년에 커스텀 스킨의 한계를 보안했고, 표준 웹링크 형태(https://www.xxx) 를 가집니다. 그렇기 때문에 이 방법으로 위에 문제들을 해결할 수 있게 됩니다.

위에서 딥링크가 무엇인지 알아봤으니, 실제로 적용해볼까요?

iOS는 진행하지 않고 Android에서 실무에서 어떻게 적용할 수 있는 지 알아보려고 합니다.

안드로이드에서 간단하게 딥링크를 테스트할 수 있는 방법은 무엇인가요?

우선, 커스텀 스킴을({scheme}://{host}) 설정해주어야 합니다.

요구사항은 다음과 같습니다.

  • matee://open 으로 MainActivity를 열어야 한다.

그렇기 때문에 아래와 같이 AndroidManifest.xml에 intent-filter를 설정해줍니다.

 <activity
  android:name="com.kwanhee.example.MainActivity"
  ...>
	<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="matee"
          android:host="open"/>
  </intent-filter>
</activity>

위 처럼 설정한 뒤, 애뮬레이터를 실행시킵니다.

그 이후에 터미널에 아래 명령어를 입력하면, 해당 matee 스킴을 가진 앱을 실행시키며, open 호스트 데이터를 가진 Activity를 열게 됩니다.

adb shell am start \
  -a android.intent.action.VIEW \
  -d "matee://open"

간단하게 커스텀 스킴을 사용하여 테스트 하는 방법입니다.

링크 전달도 다음과 같이 할 수 있습니다.

저는 슬랙이라는 메신저 툴을 사용했고, 슬랙에서 matee://app-launch 커스텀 링크를 메시지로 입력하면 하이퍼링크가 되어 등록된 앱의 커스텀 스킴이 존재한다면 이동하는 것을 알 수 있습니다.

그렇다면 해당 앱이 존재하지 않으면 어떻게 될까요?

슬랙에서는 해당 링크를 열 수 없다고 알림 메시지가 나옵니다.

그렇기 때문에 앱이 설치되지 않다면, 구글 플레이 스토어로 이동시키는 전략을 세워 앱의 다운로드를 유도해보려고 합니다.

그러기 위해서는 표준 웹링크를 사용하는 App Link 를 사용할 수 있어야 합니다.

Android에서 App Link는 어떻게 구현하나요?

우선, 안드로이드 manifest 설정은 아래와 같습니다.

딥링크와 앱링크 방식 모두 데이터로 추가해둡니다.

<activity
            android:name="com.livinai.presentation.MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize"
            android:theme="@style/Theme.AppCompat.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter
                android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:host="matee.livincare.kr" />
                <data android:pathPrefix="/app-launch" /> <!--: https://matee.livincare.kr/app-launch -->
            </intent-filter>

            <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="matee"/>
                <data android:host="app-launch"/> <!--: matee://app-launch -->
            </intent-filter>
        </activity>

Android App Link에서 사용하는 디지털 인증 에셋 JSON 파일 (assetlinks.json)은 앱과 도메인 간의 신뢰 관계를 증명하는 핵심 요소입니다. 이 파일을 통해 Android는 “이 도메인은 이 앱에서 공식적으로 소유하고 있다”고 판단하게 되는 것입니다.

형식은 아래와 같습니다.

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "[your-package-name]",
    "sha256_cert_fingerprints":
    ["[your-application-sha256]"]
  }
}]

*구글 플레이 스토어 등록 시, sha256키 변경되니 구글 플레이 스토어 올릴 경우, sha256 키로 변경해야 합니다.

만약에 SHA256키 추출을 원한다면, 터미널에 아래 명령어를 입력해주세요!

./gradlew signingReport

이제 assetlinks.json 파일 내용을 작성하셨다면, 웹에 호스팅(게시)해야 합니다.

웹 사이트의 아래 path처럼 json 파일이 들어가 있어야 합니다.

https://[your-domain-name]/.well-known/assetlinks.json

저는 Nginx로 정적 빌드 리액트 파일을 서빙했고, 링크 접속 시 아래처럼 나오게 됩니다.

그런데 여기서 중요한 부분은 에셋 파일도 호스팅해야 한다는 부분입니다.

nginx 설정 시, 정적 파일만 서빙하면 안되고, 위처럼 .well-knwon/assetlinks.json 경로로 웹사이트 접속시 json 파일이 보여야 합니다.

server {
	location / { // 웹 정적 파일 서빙
		root /home/livinai/matee_front/dist;
		try_files $uri $uri/ /index.html =404;
	}
	location /.well-known/ { // JSON Digital Asset 인증 파일 호스팅
    root /home/livinai/matee_front;
    try_files $uri $uri/ /index.html =404;
	}
}

웹 코드도 작성해야하나요?

네 맞습니다.

저는 React + Vite 로 프로젝트를 셋팅하고 단순한 코드를 작성했습니다.

초기 셋팅하는 코드는 아래와 같습니다.

npm create vite@latest my-app -- --template react
cd my-app
npm install

그 이후, react-routing으로 라우팅 처리를 해줍니다.

npm install react-router-dom
// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';
import './index.css';

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

// src/App.jsx
import { Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import AppLaunch from './pages/AppLaunch';

function App() {
  return (
    <div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/app-launch" element={<AppLaunch />} />
      </Routes>
    </div>
  );
}

export default App;

최종적으로 코드를 아래처럼 작성하면 됩니다.

앱이 존재하면 앱으로 이동시키고, 앱이 존재하지 않다면 플레이 스토어로 이동시키는 로직을 작성하면 됩니다.

import { useEffect } from "react";

// src/pages/AppLaunch.jsx
const AppLaunch = () => {
    // React useEffect 예시
    useEffect(() => {
        // 1) Intent URI 에 앱 패키지명·fallback URL·스킴 등을 한 번에 담는다
        const intentUri =
            'intent://app-launch#Intent;' +
            'scheme=matee;' +                                              // custom scheme
            'package=com.livinai.mateeapp;' +                             // 앱 패키지
            'S.browser_fallback_url=' +
            encodeURIComponent(
                'https://play.google.com/store/apps/details?id=com.livinai.mateeapp'
            ) + ';' +
            'end';

        // 2) 한 번만 리다이렉트
        window.location.replace(intentUri);
    }, []);

    return (
        <></>
    );
};

export default AppLaunch;

저는 위 코드에서 Intent 스킴을 사용했습니다.

디버그에서 테스트할 때, https://matee.livincare.kr/app-launch 링크를 클릭하니 앱을 열어주지 않더라구요.. 그래서 앱으로 이동하지 않길래 추가해두었습니다.

Intent 스킴은 뭔가요?

Intent 스킴은 Android App Link가 나오기 전에 Android 웹뷰에서 사용했던 딥링크 유형입니다. iOS에서는 Intent 스킴을 사용할 수 없기 때문에 구분하는 로직이 필요할 것 같습니다.

꼭 Intent 스킴을 사용해야 하나요?

꼭 그렇지 않은 것 같습니다.

개발 환경에서는 https://matee.livincare.kr/app-launch 링크를 클릭하니 앱을 열어주지 않은 이유가 앱에서 설정을 따로 해주어야 하더라구요.

아래 처럼 앱 설정에서 등록한 웹 주소를 지원되게 허용해주어야 한다고 합니다.

플레이 스토어 배포 후 설치된 앱을 확인해보니 위 웹 주소 허용이 되어있는 것을 확인했고, Intent 스킴을 사용하지 않더라도 잘 작동하는 것을 확인했습니다.

최종적으로 테스트하기 위한 설정이 완료되었다면, 아래 명령어를 터미널에 넣어주면 동작합니다.

adb shell am start -a android.intent.action.VIEW \
  -c android.intent.category.BROWSABLE \
  -d "https://matee.livincare.kr/app-launch"

웹링크를 클릭하더라도 https://matee.livincare.kr/app-launch 링크를 클릭해도 잘 동작합니다.

Ref.


Android 앱 링크 처리하기  |  App architecture  |  Android Developers

딥링크(Deep Link) | 토스페이먼츠 개발자센터

Android, iOS 웹뷰에서 딥링크 열기 | 토스페이먼츠 개발자센터

딥링크 실전에서 잘 사용하는 방법 | 토스페이먼츠 개발자센터

딥링크의 모든것(feat. App Link, Universal Link, Deferred DeepLink) | 헤이딜러 기술블로그

profile
Allright!

0개의 댓글