기록의 습관화
article thumbnail
Published 2023. 9. 30. 23:39
WebView에 관하여 React Native

WebView 요즘 정말 핫한 주제 중에 하나이죠.

많은 시중의 앱들이 WebView와 + Native 앱을 합쳐서 개발을 빠르게 진행하는 걸로 알려져 있는데요

이번 포스트에서는 웹 개발자의 관점에서 WebView란 무엇이고, 왜 쓰고, 어떤 장단점들을 가지고 있는지에 대해

서 좀 더 자세히 알아볼까 합니다.

그럼 시작해 볼까요?


WebView란?

WebView는 모바일 애플리케이션에서 웹 콘텐츠를 표시하는 데 사용되는 UI 컴포넌트입니다.

이를 사용하면 애플리케이션 내에서 별도의 웹 브라우저를 열지 않고도 웹 페이지나 웹 앱을 로드할 수 있습니다.

iOS와 Android에서 WebView의 동작 방식은 약간 다르지만, 기본 개념은 비슷합니다.

iOS (WebKit)

  • iOS에서는 WKWebView 클래스를 사용하여 WebView를 구현합니다.
  • 이 클래스는 WebKit 엔진을 기반으로 하며, Safari 브라우저와 동일한 렌더링 엔진을 사용합니다.
  • Objective-C나 Swift를 사용하여 WKWebView를 커스터마이즈 할 수 있으며, 자바스크립트와 네이티브 코드 간의 상호 작용도 가능합니다.

WKWebView | Apple Developer Documentation

 

WKWebView | Apple Developer Documentation

An object that displays interactive web content, such as for an in-app browser.

developer.apple.com

Android (WebView)

  • Android에서는 WebView 클래스를 사용하여 웹 콘텐츠를 표시합니다.
  • 이 클래스는 Android의 웹 렌더링 엔진을 사용합니다. 이 엔진은 버전에 따라 다르지만, 일반적으로 Chromium 기반입니다.
  • Java나 Kotlin을 사용하여 Android WebView를 커스터마이즈 할 수 있습니다. 또한, 자바스크립트와 네이티브 앱 코드 간의 통신도 가능합니다.

WebView에서 웹 앱 빌드 | Android 개발자 | Android Developers

 

WebView에서 웹 앱 빌드  |  Android 개발자  |  Android Developers

WebView에서 웹 앱 빌드 컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. 웹 애플리케이션 또는 웹페이지만 클라이언트 애플리케이션의 일부로 제공하려는 경

developer.android.com


왜 쓰이는가?

  1. 빠른 개발
  • iOS와 Android 등 여러 플랫폼에서 동일한 UI와 동일한 코드를 통해서 개발을 할 수 있게 되어 빠른 개발이 가능합니다.
  1. 쉬운 업데이트
  • 원래의 앱 심사에는 최초 심사과정을 제외하고 1 ~ 3일 정도의 시간이 소요됩니다. 하지만 WebView 환경에서 개발을 진행하게 되면 web application의 배포과정만 거치면 되므로 바로바로 업데이트 적용이 가능하겠죠?
  • (이러한 문제를 해결하기 위해 React Native 환경에서는 code push 기능을 제공합니다.)
  1. 테스트 용이성
  • 기존 Web 환경에서 사용하던 개발과 동일한 방식으로 디버깅을 진행할 수 있습니다. Native App이나 React Native 환경에서 개발을 진행해 보신 분들은 아시겠지만 Chrome 환경에서의 디버깅에서 가져올 수 있는 편리함은 따라올 수 없다고 생각합니다.
  • 만약 React Query나 Redux를 내부적으로 사용해 DevTools 기능을 사용하고 있다면 이에 대해서도 동일하게 사용할 수 있습니다.

WebView 사용의 단점

  1. native 스러운가?를 많이 따져봐야 합니다.
  • 결국 유저 사용성(UX)의 관점에서 웹과 앱의 경계를 넘나들며 앱이 부자연스럽다고 느끼게 되면
  • 이 부분에 있어서는 WebView 사용의 단점으로 부각될 수 있겠죠. 이 부분을 유념하면서 사용을 해야 합니다.
  1. 플랫폼 간 css 애니메이션 차이
  • 동일한 css 코드를 사용한다 하더라도 iOS → WKWebView와 Android → WebView는 동일한 웹 렌더링 엔진을 사용하지 않기 때문에 실제로 구동해 보면 예상했던 방향과 다르게 나타날 수 있습니다.
  • 실제 translateX와 translateY같이 특정 css animation의 경우 iOS에서 프레임이 120 FPS를 못 받쳐 주는 경우가 있는데 BottomSheet를 사용하거나 다른 애니메이션 코드를 사용하더라도 이질감이 느껴지는 부분이 있을 수 있습니다.
  1. 비교적 느린 렌더링 시간
  • 네이티브 앱은 스토어에 배포를 할 시 빌드가 완료된 상태로 올라가지만 WebView의 경우 사용자가 페이지를 방문할 시 페이지에 필요한 리소스들을 다운로드하고 사용하기 때문에 좀 더 시간이 걸리고 로딩 상태에 걸리게 됩니다. 이를 Skeleton UI나 Loading 컴포넌트로 대체를 할 수 있긴 하지만 오래된 로딩 상태는 사용자를 떠나게 하는 요인 중 하나니 주의가 필요합니다.
  1. 심사의 거부
  • WebView 기능만 포함한 앱은 앱 심사에서 거절당할 수 있습니다.
  • WebView가 대중화되고 난 뒤 많은 사람들이 쉽게 WebView만 앱을 개발하고 중간에 웹 사이트를 바꿔버리거나 너무 많은 앱들을 만들어내 버려서 스토어 심사에서 WebView만을 포함한 앱은 심사에서 거절을 해버립니다.

WebView의 꽃 Bridge 통신

그럼 앱 자체에서 WebView에게 데이터를 전달해 주고 싶은 경우에는 어떻게 할까요?

또한 반대의 경우도 가능해야겠죠.

실제 사례로 만약 핸드폰을 이용해서 사진을 찍고 이 사진을 WebView 브라우저에서 띄우고 싶다면

Bridge 통신을 이용하여 데이터를 전달하게 됩니다.

이 Bridge 통신은 JavaScript 함수 호출과 네이티브 함수 호출 사이에 인터페이스를 제공하여

두 환경 간에 데이터를 주고받을 수 있게 됩니다.

각 플랫폼별 Bridge 방식에는 조금씩 차이가 존재합니다.

Android

  1. 네이티브 → 웹: Android에서는 WebViewloadUrl("javascript:...") 메서드를 사용하여 웹 콘텐츠 내에서 JavaScript 코드를 실행할 수 있습니다.
  2. 웹 → 네이티브: addJavascriptInterface 메서드를 사용하여 JavaScript에서 호출 가능한 네이티브 메서드를 등록할 수 있습니다.

IOS

  1. 네이티브 → 웹: WKWebViewevaluateJavaScript(_:completionHandler:) 메서드를 사용하여 JavaScript 코드를 실행할 수 있습니다.
  2. 웹 → 네이티브: WKScriptMessageHandler 프로토콜을 구현하여 웹 콘텐츠에서 보낸 메시지를 받을 수 있습니다.

React Native

만약 React Native 환경에서 Bridge 방식을 보고 싶으시다면 직접 위의 방식을 구현한 다음의 글을 참고하셔도 좋을 것 같네요 😃

JavaScript webview에서 카메라 / 영상 촬영 기능 사용하기

 

JavaScript webview에서 카메라 / 영상 촬영 기능 사용하기

이번 포스트에서는 webview 환경에서 카메라를 다루는 법에 대해서 적어볼까 합니다. 요즘 진행 중인 프로젝트에서 원래는 React Native 기반으로만 프로젝트를 진행하려고 하였는데 React Native 환경

ww8007-learn.tistory.com

  • 공식 문서에도 자세한 설명이 포함되어 있습니다.

 


Bridge 통신의 문제점

하지만 Bridge 통신은 가장 큰 문제점이 존재하는데 바로 보안에 취약할 수 있다는 것입니다.

주로 다음과 같은 이유에서 문제점이 발생할 수 있습니다.

  1. 코드 실행
  2. WebView는 기본적으로 HTML, JavaScript 등을 실행할 수 있는 환경을 제공합니다. 악의적인 코드가 이를 이용하여 앱 내부 또는 사용자의 데이터에 접근할 가능성이 있습니다.
  3. URL 로딩
  4. 앱 내 WebView가 외부 URL을 로드할 경우, 중간자 공격(Man-in-the-Middle Attack) 같은 네트워크 공격에 취약할 수 있습니다.
  5. 자바스크립트 인터페이스
  6. 네이티브 앱과 WebView 사이에 데이터를 주고받기 위해 자주 사용되는 JavaScript 인터페이스가 잘못 구현된 경우, 이를 악용하는 공격이 가능합니다.
  7. 세션 피싱
  8. WebView를 통해 사용자의 로그인 정보나 쿠키 등을 노출시킬 위험이 있습니다. 이는 세션 피싱(Session Phishing) 공격으로 이어질 수 있습니다.
  9. XSS 공격
  10. 앱 내 WebView에서 표시되는 웹 페이지가 외부로부터 데이터를 받는다면, 크로스-사이트 스크립팅(XSS) 공격에 취약해질 수 있습니다.
  11. 데이터 노출
  12. WebView에서 실행되는 자바스크립트 코드가 모바일 앱의 로컬 파일 시스템에 접근할 수 있다면, 민감한 데이터가 노출될 위험이 있습니다.
  13. 보안 정책 미적용
  14. 웹 페이지와 동일한 보안 메커니즘을 WebView에 적용하지 않을 경우, 위험이 증가합니다. 예를 들어, Content Security Policy (CSP)를 적용하지 않으면 스크립트 공격 위험이 증가합니다.
  15. 버전 업데이트 부재
  16. WebView 컴포넌트 자체가 오래된 경우, 알려진 보안 취약점이 패치되지 않을 수 있습니다.
  17. 사용자 신원 확인
  18. WebView를 사용할 때, 일반적인 브라우저에서처럼 안전하게 사용자 인증을 처리하기 어렵습니다. 예를 들어, 브라우저는 HTTPS의 유효성을 확인하는 UI를 제공하지만, WebView에서는 이것이 명확하지 않을 수 있습니다.

WebView를 이용해서 개발하며 마주친 상황들

이제 전반적인 WebView 사용에 대한 설명은 마무리가 되었습니다.

이제 좀 더 세부적인 내용으로 들어가서 WebView로 개발을 하면서 제가 마주쳤던 문제와 상황들에 대해서 설명을 드려볼까 합니다.

1. 앱인데도 웹 페이지처럼 Drag가 되는 문제

시중에서 앱을 사용하다가 다음과 같이 드래그가 되는 경우를 경험하신 적이 종종 있으실 겁니다.

이건 십중팔구 WebView를 이용하여 개발을 한 것인데요

이 부분에 이질감이 느껴질 수 있으니 css 속성을 이용해서 제거해 주는 편이 좋습니다.

* {
    -webkit-tap-highlight-color: transparent;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -o-user-select: none;
  user-select: none;
  -webkit-user-drag: none;
  -khtml-user-drag: none;
  -moz-user-drag: none;
  -o-user-drag: none;
  user-drag: none;
}

2. 페이지 전환 애니메이션

WebView 환경은 단일 브라우저로 제공이 되기 때문에 웹 페이지에서 페이지 애니메이션을 제공하지 않는 한

Native처럼 화면 전환 효과가 자동으로 나타나지 않습니다.

이 부분에 대해서 직접 구현을 하거나 native Stack 효과를 따로 주거나 하는 방식을 사용할 수 있는데

만약 관심 있는 분들은 다음 포스트를 참고하시면 될 것 같습니다.

React Native Webview와 expo router에서 페이지 전환 애니메이션 전환 효과 구현하기

 

React Native Webview와 expo router에서 페이지 전환 애니메이션 전환 효과 구현하기

이번 포스트에서는 React Native Webview에서 페이지 전환 애니메이션에 대해서 다뤄보려고 합니다. 처음에 검색해서 얕봤다가 되게 고생한 기능 중에 하나네요 😂 웹 보다 사용자 경험이 좋다고 느

ww8007-learn.tistory.com

3. 아이템에 :active 효과 주기

기본 Web 개발과 다르게 WebView 앱의 환경 이므로

pointer: cursor;

와 같은 속성을 설정하여도 아무런 의미가 없습니다.

앱의 사용자는 모바일 환경 이므로 마우스 커서가 아닌 터치 환경 이므로

내가 누르고 싶은 아이템을 정확하게 눌렀는가?를 사용자에게 인식시켜주는 편이 좋습니다.

css를 통해 추가해 줍시다.

transition: color 0.3s ease-in-out, background-color 0.3s ease-in-out;
&:active {
  background-color: ${theme.colors[activeButtonColor]};
    color: ${theme.colors.white};
}

4. Background Mode

앱의 환경에는 Foreground 환경과 Background 환경이 존재합니다.

Foreground : 앱이 사용 중

Background : 앱이 사용 중이지 않음

앱이 유휴 상태에 들어가면 React Native를 사용한 앱 기준으로는 특별한 설정을 안 하는 이상 모든 동작이 멈추게 됩니다. 만약 Background Mode에서도 실행되어야 할 중요한 태스크가 있다면 등록을 해서 사용해 줄 수 있습니다.

다음은 React Native 환경에서 Background Mode에 대한 Task를 등록하는 방식입니다.

Headless JS · React Native

 

Headless JS · React Native

Headless JS is a way to run tasks in JavaScript while your app is in the background. It can be used, for example, to sync fresh data, handle push notifications, or play music.

reactnative.dev

https://github.com/transistorsoft/react-native-background-fetch

 

GitHub - transistorsoft/react-native-background-fetch: Periodic callbacks in the background for both IOS and Android

Periodic callbacks in the background for both IOS and Android - GitHub - transistorsoft/react-native-background-fetch: Periodic callbacks in the background for both IOS and Android

github.com

만약 Background Mode Timer 구현에 대한 구현이 궁금하시다면 다음 포스트를 참고해 주세요

 

마무리

이렇게 하여 webview에 대해서 알아보았습니다.

편하게 보이기도 하지만 결국 이렇게 신경 써줘야 하는 부분이 있는 것도 사실 입니다.

(물론 ios, android 둘 다 개발하는 것 보단 편할 듯 합니다...?)

실제로도 프로젝트에서 React Native + WebView 환경으로 배포를 해보니 개발경험이 좋았던 점을 고려한다면

아마 자주 애용할 것 같네요 😃

profile

기록의 습관화

@ww8007

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!