본문 바로가기
프로그래밍 개발/React Native

React Native - 딥링크(Deep Link) Ios, Android 구현하기

by Jinseok Kim 2021. 10. 6.
반응형

 

딥링크란

 

  •  딥링크는 특정 페이지에 도달 할 수 있는 링크를 말합니다. 그렇다면 모바일 딥링크란 모바일 어플리케이션의 특정 페이지에 도달 할 수 있는 링크를 말하는 것입니다.
  • 가끔씩 모바일로 웹 서핑을 하다가, 어떤 버튼을 눌렀는데 네이티브 앱으로 바로 이동하는 기능을 해본적이 있을 것인데 그것이 바로 '모바일 딥링크'를 이용하여, 특정 앱 페이지로 들어가는 것입니다.

 

 

 

 

딥링크의 종류

 

  • 친구들과 특정 웹 페이지를 공유할 때 자주 사용하는 웹 URL(예를 들어, https://k0502s.tistory.com/category/React%20Native) 처럼, 모바일에 어플리케이션에도 특정 페이지에 들어갈 수 있는 링크가 있는 것이라고 말할 수 있습니다.
  • 딥링크의 형태는 앱 스킴(URL 스킴) 혹은 일반적인 https:// 링크 두 가지 형태를 둘다 지원합니다. 즉 app://open.my.app 혹은  https://www.example.com  두 형태를 모두 지원합니다.  또한, 필요한 앱을 직접 선택할 수 있도록 한다는 특징이 있습니다.
  • 웹(WWW) 어플리케이션이 http:// 나 https:// 프로토콜을 가지고 있는 것처럼, 모바일 어플레케이션도 각자의 프로토콜을 가지고 있어 유튜브는 youtube://, 멜론(아이폰)은 meloniphone://, 벅스는 bugs3:// 프로토콜을 가지고 있습니다.

 

  • 이후 딥링크의 앱 스킴 뿐문 아니라 애플과 구글 개발자들이 인터넷 사이트의 고유 도메인 또한 딥링크처럼 사용하기 위하여 유니버설 링크(Universal Link) 앱 링크(App Link)라는 것들을 만들어 냈습니다. 하지만 유니버설, 앱 링크 각자 애플 앱, 안드로이드 앱에서만 기능들을 완벽히 사용할 수 있는 호환성에 대한 단점이 있습니다.

 

 

 

딥링크 구현하기

 

 

 

1.  IOS 환경 세팅

우선 IOS 의 딥링크 구현을 위해서는 react native 프로젝트를 생성했다는 가정하에 IOS 폴터 안의 프로젝트이름/AppDelegate.m에 다음 내용을 추가해야한다.

 

#import <React/RCTLinkingManager.h> // 파일 상단에 추가

...

// `@end`위에다 추가해야합니다
- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}

 

여기서 주의 할점은 #import <React/RCTLinkingManager.h> 가 상단 쪽아닌 다른 곳에 추가하면 빌드 에러가 등장하니 조심해야 한다.

 

AppDelegate에 설정을 완료하였으면 xocde로 프로젝트를 열고 

프로젝트 폴더 클릭 -> targets -> 타겟 프로젝트 -> info탭 -> URL Types에 + 버튼을 누른 후 Identifier와 URL Schemes란에 허용할 이름 입력을 해줘야 합니다.

 

 

위와 같이 IdentifierURL Schemes을 설정해주시면 설정해주신 이름으로 앞으로 딥링크의  testmyapp://식으로 프로토콜로 사용할 것입니다.

 

 

마지막으로 pod installreact-native run-ios로 재빌드하면 IOS의 딥링크 환경 세팅은 마무리되었습니다.

 

 

 

 

 

 

 

 

 

2.  Adroid 환경 세팅

 

android 세팅 또한 app/src/main에 위치하고 있는 AndroidManifest.xml파일에 아래의 코드를 세팅해주셔야합니다. 

<data android:scheme="tudal-unlisted" />이 부분에서 스키마 값 이름이 딥링크의 프로토콜 이름이라고 보면 되겠습니다.

 

<activity 
  ... >
	// activity 블록 안에 추가애햐 합니다.
  <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="testmyapp" />
  </intent-filter>  
</activity>

 

코드를 세팅해주었으면 ios와 마찬가지로 react-native run-android로 재빌드 해주시고 빌드에 성공하면 안드로이드 또한 환경 세팅이 완료되었습니다.

 

 

 

 

 

 

 

 

 

 

3.  프론트 프로젝트 세팅 (android, ios 공통)

 

환경세팅이 완료되었으면 react native 프로젝트마다 있는 뿌리인 컴포넌트 AppContainer에 앱이 켜지면 곧바로 설정해준 딥링크를 통해 지정한 스크린으로 이동하도록 하는 로직을 추가해주어야 합니다.

 

해당 앱이 디바이스에 깔려있다는 전제 하에 testmyapp://home와 같은 딥링크를 누르게 되면 곧바로 앱이 켜지며 해당 딥링크의 정보에 따라 스크린 이동이 자동으로 되는 것이 목적입니다.

 

 

 

Linking.getInitialURL(), Linking.addEventListener()으로 딥링크로 들어온 링크를 가져와 프론트 단에서 사용할 수 있게 합니다. 

 

아래처럼 딥링크를 통해 들어온 딥링크의 url을 이용하여 네비게이션 라우터를 이용한 스크린 이동이 가능합니다.

import React, {useEffect} from 'react';
import {Linking} from 'react-native';

.......

useEffect(() => {
     	Linking.getInitialURL()			// 최초 실행 시에 Universal link 또는 URL scheme요청이 있었을 때 여기서 찾을 수 있음 
     		.then(value => {
       			Alert.alert('getInitialURL', value);
     	})
        
         Linking.addEventListener('url', (e) => {		// 앱이 실행되어있는 상태에서 요청이 왔을 때 처리하는 이벤트 등록
      		const route = e.url.replace(/.*?:\/\//g, '');
      		navigation.navigate(route)
    	});

    	return () => {	
      			Linking.removeEventListener('url', (e) => {	
          		Alert.alert('remove e.url', e.url);
      		});
    	};
    })

 

 

하지만 위의 방법보다 정규식 표현과 같이 복잡한 로직을 짜지 않더라도 더 효율적이고 깔끔하게 딥링크를 활용하는 방법이 react native 자체 기능에 존재합니다.

 

 

마찬가지로 AppContainer에서 작업이 필요합니다.

 

 

react native 공식 독스에서 deep-link의 third-party-integrations라는 파트의 참고하면 더 이해할 수 있겠습니다.

https://reactnavigation.org/docs/deep-linking/#third-party-integrations

 

https://reactnavigation.org/docs/deep-linking/#third-party-integrations

 

reactnavigation.org

 

 

일단 linking 이라는 객체를 만들어주어 아래와 같이 설정해줍니다. 

 

  • prefixes에는 처음 딥링크를 위해 세팅 설정해준 프로토콜 이름 값을 삽입해주어야 합니다.
  • subscribe는 딥링크 활용을 위한 native에서 설정해준 것이다. 즉  addEventListener로 받은 딥링크 url을 subscribe에 넣어주어야 합니다.
const AppContainer = () => {

const linking = {
 //디폴트 프로토콜 설정 필요
    prefixes: [
      'https://...',
      'http://localhost:3000',
      'testmyapp://',
    ],

    async getInitialURL() {
      const url = await Linking.getInitialURL();

      if (url != null) {
        return url;
      }

      return null;
    },

//받아준 딥링크 url을 subscribe에 넣어줘야 한다
    subscribe(listener) {
      console.log('linking subscribe to ', listener);
      const onReceiveURL = (event) => {
        const { url } = event;
        console.log('link has url', url, event);
        return listener(url);
      };

      Linking.addEventListener('url', onReceiveURL);
      return () => {
        console.log('linking unsubscribe to ', listener);
        Linking.removeEventListener('url', onReceiveURL);
      };
    },
    config, //스텍 네비게이션 디렉토리 정보 설정 필요
  };
  
  
  ...........
  
  
  
// linking을 프로젝트 전체를 아우르고 있는 NavigationContainer에 props 해줘야합니다.
return (
    <NavigationContainer
      ref={ref}
      linking={linking}
      documentTitle={{ enabled: false }}
    >
      <SecurityProvider navigate={(args) => ref.current?.navigate(args)}>
        <RootNav />
        <FirebaseContainer />
      </SecurityProvider>
    </NavigationContainer>
  );
  
  }

 

 

 

const config = {
    screens: {
      Drawer: {
        screens: {
          Main: {
            screens: {
              Home: {
                screens: {
                  HomeIndex: '/home',
                  TalkIndex: '/talks',
                  MypageIndex: '/mypages',
                },
              },
              SellerList: '/sellerlist',
              ProductList: '/productlist',
              ProductDetails: '/products/:id',
              MypageNotice: '/mypages/notices',
              CustomerIndex: '/customer',
              MypageAgreement: '/mypages/agreements',
              MypageInvest: '/mypages/invest',
 			
         	  ....
            
            
            },
          },
        },
      },
    },
  };

 

  • 여기서 config는 프로젝트 전체의 stack 네비게이션의 스크린 디렉토리를 정확하게 삽입해야합니다. 위는 그 예시입니다. 이 디렉토리 정보를 통해 딥링크가 들어오면 정규식 표현을 써서 네비게이션 라우터를 쓰지 않더라도 바로 원하는 스크린으로 이동할 수 있게 됩니다.
  • key가 실제 스텍 네비게이션에서 이동을 위해 설정한 네임입니다.
  • value는 addEventListener로받은 딥링크 url을 구별하기 위한 값들이라고 볼 수 있는데, 즉 프로토콜의 뒷부분 예를 들어 testmyapp://home의 home 부분이라고 보면 됩니다.
  • 이렇게 딥링크를 구별하여 곧바로 key의 네비게이션 이름과 매칭하여 구별 후 자동으로 스크린 이동이 가능하게 하는 시스템입니다.
  • :id와 같이 콜론을 해주게 된다면 :id에 들어오는 고유의 id값에 따른 상세조회 스크린 또한 이동할 수 있다는 것이 매우 효율적이라고 볼 수 있습니다.

 

 

 

 

 

4. 시뮬레이터에서 딥링크가 잘 작동하는지 테스트하기

 

아래의 명령어를 통해 ios, android 각각의 OS별 딥링크가 잘작동하는지 테스트가 가능합니다.

 

  • android: $ npx uri-scheme open testmyapp://home --android
  • ios: $ npx uri-scheme open testmyapp://home --ios

 

 

 

반응형

댓글