Deep Link 구현하기

dayglow·2024년 1월 26일

React Native

목록 보기
1/2

Deep Link - 특정 URI 로 이동할 때 모바일 앱을 실행하여 해당 앱의 특정 페이지로 이동할 수 있는 기능입니다.

구현 방식

현재 구현된 deep Link 방식은 React Navigation에서 제공해주는 linking 방식으로 ios, android 설정 파일에 scheme 을 추가하여 모바일에서 외부로부터 링크를 통해 URL 에 적힌 scheme를 앱과 매칭시켜 앱을 실행시키고 NavigationContainer 안에 넣어준 object 형식의 주소 데이터 통해 페이지를 이동시키는 방식입니다.

IOS ( ios/{appName}/AppDelegate.mm, Info.plist ) 설정 추가

AppDelegate.mm

// iOS 8.x or older
#import <React/RCTLinkingManager.h>

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  return [RCTLinkingManager application:application openURL:url
                      sourceApplication:sourceApplication annotation:annotation];
}

// iOS 9.x or newer
- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
 return [RCTLinkingManager application:application
                  continueUserActivity:userActivity
                    restorationHandler:restorationHandler];
}

- (BOOL)application:(UIApplication *)application
        continueUserActivity:(NSUserActivity *)userActivity
        restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
    return [RCTLinkingManager application:application
                     continueUserActivity:userActivity
                       restorationHandler:restorationHandler];
}

Info.plist

<key>LSApplicationQueriesSchemes</key>
<array>
	<!-- :// 은 생략하고 scheme 이름만 넣는다. -->
	<string>testScheme</string> 
</array>

Android ( android/app/src/main/AndroidManifest.xml ) 설정 추가

<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="testScheme"/>
</intent-filter>

linking.js

import {Linking} from 'react-native';

const linking = {
  prefixes: ['testScheme://'],

  // IOS && ANDROID : 앱이 딥링크로 처음 실행될때, 앱이 열려있지 않을 때
  // getInitialURL(): 앱 실행이 앱 링크에 의해 트리거된 경우 링크 url을 제공하고 그렇지 않으면 null
  async getInitialURL() {
    const url = await Linking.getInitialURL();
    if (url) {
      return url;
    }
    return null;
  },

  config: {
    screens: {
      Login: 'login',
      SignUp: 'signUp',
      // 다른 화면에 대한 매핑
    },
  },
};

export default linking;

prefixes를 통해 scheme을 확인할 수 있고 config를 통해 원하는 페이지에 매핑시켜 페이지로 이동시킬 수 있습니다.

import linking from './src/utils/linking';

<NavigationContainer linking={linking}>

실행 방법

터미널 창에 아래와 같은 명령어를 입력하면 실행이 됩니다.

npx uri-scheme open [your deep link] --[ios|android]

예시

npx uri-scheme open "testScheme://signUp" --ios 
npx uri-scheme open "testScheme://signUp" --android

문제점

해당 deep link 에는 여러 문제점이 있습니다.

  1. 위에서 설명했던 것 처럼 store 연결이 안됩니다. 즉, 앱 설치 되었을때만 유효합니다.
  2. 원하는 스킴을 아무나 만들 수 있어서 같은 스킴을 사용하는 경우가 생길 수 있습니다.
    (Scheme의 주인이 없습니다.)
    그래서, 같은 스킴이 있을경우 Android는 어떤앱으로 열지 선택하는 팝업이 뜨고, iOS는 마지막에 설치한 앱이 열립니다.
  3. ios 에서 앱을 백그라운드에 대기 시키고 명령어를 실행하면 페이지가 이동이 안됩니다.
    ( 앱 종료 하고 나서 실행하면 잘 이동됩니다.)
  4. 자동 로그인할때 로그인 후 메인 페이지로 이동되는 navigation과 충돌이 발생했지만
    해당 문제는 react-native 의 Linking.getInitialURL() 을 통해 deep Link 가 있다면 navigation을 실행시키지 않도록 하여 해결했습니다.
    ( 해결 )

혹시 해당 문제에 대해 해결방법을 알고 계신다면 공유 부탁드리겠습니다.

0개의 댓글