📌 딥링크에 대한 자세한 내용은 여기를 클릭하면 된다.
- 개발 플랫폼: macOS
- 개발 언어: JavaScript, TypeScript
- 개발 프레임워크: React Native(0.68.5)
- 버전 관리: GitHub
- 개발 도구: Visual Studio Code
- 배포 환경: Xcode(14.1), Android Studio(chipmunk 2021.2.1)
url
에 따라 목적에 맞는 앱 페이지 연결url
에 따라 navigation
을 이용하여 원하는 페이지로 redirect
url
에 포함되어 있는 query
전달 및 해당 함수 실행RN
을 사용하긴 하지만 URL을 통해 접속했을 때, 해당 URL을 제어해주기 위해서 다음과 같이 native
단에서 들어가야 할 필수 코딩이 있다.
ios > {프로젝트} > AppDelegate.mm
파일
// 파일 상단에 import
#import <React/RCTLinkingManager.h>
// 본문에 다음 내용 insert
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
return [RCTLinkingManager application:application openURL:url options:options];
}
다음으로 Xcode
에서 Deep link
를 설정한다.
참고로 Universal link
가 아닌 일반적인 URL Schemes
를 적용했다.
먼저, Xcode
에서 아래 이미지에 따라 들어간다.
Identifier
에 프로젝트의 Bundle ID
를 넣는다.
URL Schemes
부분에 본인이 원한하는 이름의 프로토콜 이름을 정하면 된다
ex) whkwon
으로 지정하면 프로토콜이 커스터마이징 되어 앞으로 브라우저에서 whkwon://
딥링크를 타고 앱 접속을 시도할 수 있다.
아래와 같이 AndroidManifest.xml
파일에 intent-filter
태그를 추가한다.
android > app > src > main > AndroidManifest.xml
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</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="kwt" android:host="main" />
</intent-filter>
🔔 참고
Android
는 하기 adb
명령어를 통해 Deep link
를 실행할 수 있다.
adb shell am start -W -a android.intent.action.VIEW -d "${scheme}://${host}" ${앱 패키지명}
딥링크를 타고 들어오면 가장 먼저 어떤 URL
인지 파악해야 한다.
이를 위해 RN
은 기본적으로 Linking
컴포넌트를 지원한다.
❓ Linking
컴포넌트란 ?
- 앱 내에서
URL
을 처리하고 외부 앱이나 브라우저와의 상호작용을 관리한다.- 지정된
URL
을 사용자의 기본 웹 브라우저나 다른 앱에서 연다.- 외부 앱에서 현재 앱으로 돌아올 때 콜백을 처리할 수 있다.
Deep link
를 통해 특정 화면으로 이동시킨다.
Linking
의 여러 가지 메소드가 존재하지만, Deep link
로부터 들어오는 URL
을 파악하고 처리하기 위해선 addEventListener()
메소드가 필요하다.
const handleOpenURL = ({ url }: any) => {
const path = url.split('//')[1];
if (path.startsWith('wc?uri=')) {
const uri = decodeURIComponent(path.slice(7));
navigation.navigate('작업 처리할 컴포넌트', { uri: uri ? uri : '' });
}
};
Linking.addEventListener('url', handleOpenURL);
먼저, URL
을 listening 하여 콜백 함수를 실행한다. (제일 아래줄 코드)
콜백 함수 안에서는 path
를 잘라내기 위해 split
메소드로 //
이후의 값을 가져왔다.
if
조건문으로 path
별 원하는 결과를 수행하도록 분기점을 만들었고, 브라우저 상에서 encoding 되어 들어오는 값을 decoding 하여 최종적으로 처리를 원하는 컴포넌트에 navigation
으로 파라미터와 함께 넘겨주었다.
react-native-webview
라이브러리를 사용하여 앱 내에서 브라우저가 실행되는 in-app-browser
환경에서 작업하였다.
하지만, iOS
에서만 Custom URI Scheme
을 인식하지 못하는 문제점을 발견했다. (하기 이미지 참조)
(물론, regular한 URL 프로토콜인 http
또는 https
에서는 URL 오픈이 잘됐다.)
이를 위해 첫 번째는, info.plist
에서 LSApplicationQueriesSchemes
키 값을 추가하는 것이었다.
LSApplicationQueriesSchemes
란, Xcode
의 info에선 Queried URL Schemes
로 정의되며, 외부 앱의 URI Scheme
을 허용하는 설정이다.
info.plist
기준 아래와 같이 설정하였다.
ios > {프로젝트} > info.plist
<key>LSApplicationQueriesSchemes</key>
<array>
<!-- :// 은 생략하고 scheme 이름만 넣는다. -->
<string>customschemes</string>
</array>
하지만, 여전히 동작하지 않았다.
그 다음 Webview
파라미터인 onShouldStartLoadWithRequest
를 이용해서 원하는 action을 만들어줬다.
(참고로 react-native-webview
의 버전은 "11.23.1"
을 사용하였다.)
onShouldStartLoadWithRequest
파라미터는 링크 요청이 발생하기 전에 호출되는 콜백으로 action을 정의하는 함수이다. boolean
을 return
하는데, true
이면 해당 페이지를 load하고, false
이면 링크를 무시한다.
이를 이용해서 사전에 정한 URI Scheme
을 redirection
할 땐 Link를 Open하여 앱의 특정 페이지로 유도는 하지만, WebView
는 URI Scheme
을 load하지 않도록 설정하여 해결하였다.
<WebView
...
onShouldStartLoadWithRequest={event => {
if (event.url.startsWith('yourScheme://')) {
Linking.openURL(event.url); // link는 open하여 딥링크를 실행한다.
return false; // 하지만, WebView는 link를 load하지 않는다.
}
return true;
}}
/>
앱이 종료 된 상태로 외부에서 딥링크를 클릭했을 때, 앱은 실행되지만 Action은 하지 않는 경우다.
원인은 모든 앱이 공통적으로 처음 시작할 때 '초기화' 작업을 거치기 때문에 Linking.addEventListener
로 딥링크를 리스닝하던 작업 역시 초기화가 되어버린다.
따라서, 앱 시작 시 Linking.getInitialURL()
메소드를 사용하여 딥링크가 있는지 확인하고, 있을 경우 따로 처리를 해줘야 한다.
useEffect(() => {
const getInitURL = async () => {
const initURL = await Linking.getInitialURL(); // 없을 경우 null을 반환한다.
if (initURL) {
const path = initURL.split('//')[1];
if (path.startsWith('wc?uri=')) {
const uri = decodeURIComponent(path.slice(7));
navigation.navigate('작업 처리할 컴포넌트', { uri: uri ? uri : '' });
}
}
};
getInitURL();
}, []);
딥링크 사용성에 대한 가장 큰 목적은 '광고 성과를 높이는 것' 에 있다.
우리가 원하는 서비스를 필요로 하는 사용자에게 알리기 위해선 홍보는 필수이며, 필요성을 느낀 사용자는 클릭 하나로 우리의 서비스를 제공할 수 있어야 한다.
그런 의미에서 딥링크는 광고 성과를 최적화 할 수 있는 방법 중 하나이다.
이를 구현함으로서 서비스를 이용하기 위해 적어도 3~4번의 클릭과 불필요한 페이지 depth, 서비스를 이용하기 위해 사용자가 갖춰야 할 학습 내용 등을 모두 무시하고 단 한 번의 클릭으로 특정 페이지를 redirection
하여 바로 서비스를 이용할 수 있도록 함으로써 사용자 경험(UX) 및 편의성을 극대화하였다.