프론트엔드/모바일

[ React Native ] 요즘은 다 이거써요, Webview를 이용한 통신

잡캐헨리 2024. 3. 21. 19:19

 

React Native 는 React 를 기반으로 Mobile App을 만들수 있는 프레임 워크이다. React native 를 이용하면 하나의 코드베이스로 안드로이드, ios 모두를 지원하는 앱 (하이브리드앱) 을 만들 수있는데. 이는 개발 생산성 관점에서 볼 때 큰 이점으로 작용한다.

 

 

React Native 를 더 강력하게 하는 기술
"Webview" 

 

이러한 하이브리드 앱의 강점을 한층 더 업그레이드 할 수 있는 기술이 있는데, 바로 Webview 라는 기술이다

Webveiw 를 이용하면 어플리케이션 내부에 인터넷 브라우저를 띄울 수 있다.

 

이 둘은 과거 팝업창에서 자주 쓰이던 window.postMessage 라는 메서드를 이용해 통신할 수 있는데 이를 이용해 React native 로 Native기능 (카메라, 푸시알림, 위치정보)을 제어하고, 웹 프론트엔드를 이용해 어플리케이션의 View 를 만들 수 있는데

 

어플리케이션의 요구사항에 따라 다르겠지만 이런식으로 사용할 경우,  웹의 이점은 모두 챙기면서 Native App 을 개발하는 수고를 덜 수 있게된다.


구현방법

이를 구현하기 위해서는 message를 보내는쪽과 받는 쪽 에서 이를 핸들링할 코드를 작성해줘야하는데. 웹과 앱 모두에 작성해야 하므로 작성해줘야 할 코드는 총 4개가 된다.

 

웹 ( React, Next.js )

1. Web => APP 으로 메세지를 보냄

export const postMessageToRN = (payload: PostMessagePayload) => {
  // Next.js의 경우 Window 객체가 존재하지않는 환경 (서버)의 경우 혹은 웹뷰가 아닌 브라우저로 접근시
  // 아무것도 하지않음
  if (typeof window === "undefined" || !!window?.ReactNativeWebView) {
    return;
  }
  window?.ReactNativeWebView.postMessage(JSON.stringify(payload));
};

리액트 네이티브에서 react-native-webview 라이브러리를 이용해 웹뷰를 띄우게 되면 window객체에 ReactNativeWebView 라는 객체가 추가되게 된다. 따라서 이 객체가 존재한다면 현재 웹사이트가 리액트 네이티브의 웹뷰로 띄워져있는 상태라는것을 알 수 있다.

추가적으로 Next.js 를 사용한다면 서버환경에서는 window객체가 존재하지 않으므로 Early return 패턴으로 미리 리턴 시켜주는 코드 역시 작성해준다

 

2. App => Web 메시지를 수신

  useEffect(() => {
  	const onMessageHandler =(e:Event) =>{
    //비즈니스 로직
    }
    // 안드로이드에서는 document / IOS 에서는 window 객체를 참조한다고 한다
    document.addEventListener("message", onMessageHandler);
    return () => {
      document.removeEventListener("message", onMessageHandler);
    };
  }, []);

 

앱에서 웹으로 메시지를 보내게 되면 Web에서는 EventListner을 이용해 해당 event 를 구독할 수 있다. postMessage 의 경우 message 라는 이벤트로 트리거 되므로 해당 이벤트가 발생했을 때 사용할 코드를 적어준다.

 

이 과정에서 우여곡절이 많았는데 Android 의 경우 document 객체에 리스너를 달아줘야하고, IOS 에서는 window객체에 리스너를 달아줘야한다. 따라서 이에 따른 분기처리도 필요할 것이다

 

앱 ( React Native )

1. Web => APP 메시지를 수신

      <WebView
        source={{ uri: "당신의! 웹사이트!" }}
        // React-native-webview 모듈의 Webview 컴포넌트의 onMessage 속성에 함수를 전달
        onMessage={onMessage}
        // 밑에서 설명할 예정
        ref={webViewRef}
        {...webviewProps}
      />

웹에서 보낸 메시지를 리액트 네이티브에서 수신하기 위해서는 react-native-webview 라이브러리가 제공하는 <WebView/> 컴포넌트의 onMessage 속성으로 메세지가 수신됬을때 실행할 함수를 인자로 넘겨준다

 

2. App => Web 메세지를 보냄

const postMessageHandler = (payload:any) => {
  if (!webViewRef.current) return;
  webViewRef.current.postMessage(JSON.stringify(payload));
}

 

App에서 Web으로 메시지를 보내기 위해서는 <Webview /> 컴포넌트의 Ref를 잡아 해당 ref의 postMessage 라는 메서드를 실행시키는 형태로 메시지를 보내게 된다.

 


UX고려

+ 개인적으로 가장 좋은 UX 는 유저로 하여금 새로 익힐 필요없이 가장 익숙한 방법을 제공하는 것이라고 생각한다 . 따라서 추가적으로 Webview 로 서비스를 구성한다면 모바일 어플리케이션의 동작을 모킹해주는 작업들을 고려하는 것이 좋다.

예를 들어 모바일에서 페이지가 이동할 때 발생하는 Animation을 Framer-motion 등을 이용해 구현해주고, 뒤로가기 버튼을 눌렀을 때 Webview 의 페이지가 뒤로가기 되도록 하거나, 모달이 켜져있을 때 뒤로가기 버튼을 이용해 꺼지도록 하는등의 작업 역시 고려하는것이 좋다.