ETC/React Native

[React Native] Linking / Deep Link

도지대디 2021. 8. 7. 01:45

어플리케이션 내 컨텐츠를 외부로 공유하는 기능을 구현해야 해서, 링크를 생성하는 방법을 찾아보았다.

React Native 내장 라이브러리인 Linking, Firebase 에서 제공하는 Dynamic Links 등의 방법이 있었다.

일단은 Linking 라이브러리를 이용하여 구현을 해보고자 하였다.

 

앱 내 컨텐츠에 접근하기 위해서는 특정되어있는 경로가 필요했다

그렇기 때문에 나는 해당 페이지를 나타내는 파일 내에서 링크를 생성하거나, 

공유하고자 하는 페이지의 상위 페이지에서 링크를 생성한 후 특정 페이지의 id 값을 넘겨줘야 한다고 생각했다.

 

그래서 나는 Deep Link 에 대해 알아보았다.

 

https://help.dfinery.io/hc/ko/articles/360039757433-%EB%94%A5%EB%A7%81%ED%81%AC-Deeplink-URI%EC%8A%A4%ED%82%B4-%EC%9C%A0%EB%8B%88%EB%B2%84%EC%85%9C-%EB%A7%81%ED%81%AC-%EC%95%B1%EB%A7%81%ED%81%AC-%EA%B5%AC%EB%B6%84%EA%B3%BC-%EC%9D%B4%ED%95%B4

 

DFINERY help center

Customer Data Platform for Digital Transformation

help.dfinery.io

 

간단하게 정리해서 딥 링크란, 특정 주소를 입력하여 정해진 화면으로 이동하는 기능을 수행하는 url 이다.

앱의 경우에서는 사용자가 딥 링크에 접속하였을 때 앱이 바로 실행되어 특정 화면으로의 이동이 가능해질 것이다.

 

그렇기 때문에 나는 내가 나타내고자 하는 페이지 내에서 url 을 생성해야 한다고 생각했다.

혹은 특정 페이지의 상위 path 에서 url 을 생성한 후 내가 원하는 id 값을 넘겨줘야 한다고 생각했다.

하지만 애석하게도 Linking 라이브러리에는 url 을 생성하는 메소드가 포함되어 있지 않았다.

 

그래서 나는 Firebase 에서 제공하는 Dynamic Links 라는 기능을 사용해보고자 하였다.

 

https://firebase.google.com/docs/dynamic-links

 

Firebase 동적 링크

Firebase 동적 링크는 앱 설치 여부에 관계없이 여러 플랫폼에서 원하는 대로 작동하는 링크입니다.

firebase.google.com

다이나믹 링크는 확실히 이용하기도 편리했으며, 앱이 설치되지 않은 경우나 PC 에서 링크에 접속했을 경우를 나눠 예외 처리를 해줄 수도 있었다.

 

Url 을 생성하여 앱에 접속할 수 있는 것 까지 확인하였지만,

커스텀 링크를 생성하기 위해서는 Rest API 를 사용해야만 했다.

프로젝트 차원에서 내가 쉽게 결정하거나 변경할 수 있는 사항이 아니었기 때문에

다시 Linking 라이브러리를 잘 이용해 보기로 하였다.

 

https://reactnative.dev/docs/linking

 

Linking · React Native

Projects with Native Code Only

reactnative.dev

 

먼저 환경 설정을 끝마치고, URI Scheme 방식의 딥링크를 생성하여 앱에 접속하는 것 까지 완료하였다.

그런데 공식 문서에서 제공하는 Event Listener 등의 메소드들이 동작하지 않고 있었다.

같이 라이브러리를 공부하던 개발자 분께서도 같은 현상을 겪고 계셨다.

몇 시간이 지나고 나서 결국 문제를 발견했는데... 굉장히 어이없는 곳에 문제가 있었다.

 

// iOS 9.x or newer
#import <React/RCTLinkingManager.h>

- (BOOL)application:(UIApplication *)application
   openURL:(NSURL *)url
   options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
  return [RCTLinkingManager application:application openURL:url options:options];
}

AppDelegate.m 파일에 해당 코드를 추가하는 부분이 있었는데, 나는 import 단 바로 아래에 코드를 추가하였다.

그런데 import 를 제외한 아래 6줄의 코드를 AppDelegate.m 의 가장 하단부 end 위에 추가하니 메소드가 동작하였다.

이전에는 이런적이 단 한번도 없었는데 너무 허무하게 문제가 해결되었다.....

 

문제를 해결하였으니 path 를 지정해주는 일만 남았다.

NavigationContainer 의 props 인 linking 을 지정해주기 위한 파일을 생성하였다.

 

https://reactnavigation.org/docs/navigation-container/

 

https://reactnavigation.org/docs/navigation-container/

 

reactnavigation.org

 

파일을 생성하고 config 을 채워나갔는데, navigation 요소들을 enum 으로 모아둔 파일을 import 하여

path 를 일일히 지정해주면 쉽게 풀릴 줄 알았지만, 크나큰 오산이었다.

 

https://reactnavigation.org/docs/configuring-links/

 

https://reactnavigation.org/docs/configuring-links/

 

reactnavigation.org

 

위 문서를 몇 번씩이나 읽어보고 이해했는데, linking 에 주어질 config 는 

어플리케이션의 navigation 구성과 똑같아야 한다!!!!

 

내가 진행하고 있는 프로젝트는

 

  • App Navigator
    • Main Navigator
      • Home Navigator
        • Home Screen
        • Home Screen 2
      • Contents Navigator
        • Contents Screen
        • Contents Screen 2
    • Auth Navigator

........

 

와 같이 navigator 가 navigator 를 품고 있는 복잡한 (?) 구조로 되어있다.

그래서 더욱 해답을 찾는데 오래 걸렸던 것 같다.

 

이 글을 보는 여러분은 같은 실수를 하지 않길 바란다...

최종적으로 URI Scheme 형식으로 이루어진 딥 링크를 생성하고

페이지 마다의 path 도 설정해주어 링크 접속이 원활하게 이루어지는 것을 확인하였다.

 

이번 기능을 구현하며 다시 한번 뼈저리게 느낀 점은

내가 개발하고 있는 프로젝트의 구조를 완벽하게 이해하고 있어야 한다는 점과,

내가 사용하고자 하는 라이브러리와 구성 요소들을 완벽하게 이해해야 한다는 점이다.

 

요즘은 블로그나 유튜브를 보고 공부하는 습관을 줄이고

공식 문서를 최대한 활용하려고 노력하고 있는데,

뿌듯한 점은 이번 기능을 개발하며 참고한 자료의 90% 정도가 공식문서였다는 점이다.

 

앞으로 구현할 다른 기능들도 자세히 파악해보고 원활히 개발할 수 있었으면 좋겠다.