concept/React, Redux, RN
웹 뷰 찍먹하기 (feat. expo CLI)
오연 : Oana
2025. 3. 10. 23:30
들어가기
- 지난 해 12월, 솔로프리너 강연
- 프로그래밍 좀비 350개의 개인 앱을 만들어 월급의 7배 수익을 달성한 방법 (일 100만원의 수익)
- 왜 하필 앱이지?
- 광고 수익
- 구독 결제
웹뷰 란?
- 프레임워크에 내장된 웹 브라우저 컴포넌트로 뷰(View)의 형태로 앱에 임베딩하는 것
- App에서 웹브라우저를 이용해 화면을 보여주는 방식
웹뷰를 사용하는 이유?
- 웹 기반으로 구동되는 모듈을 앱에서 사용해야 할 때, 앱 전용 모듈을 다시 개발하는 것은 시간적으로 오래 걸리고 비효율적
웹뷰의 단점
- UX 측면에서 반응성이 약하기 때문에 페이지를 이동하거나 새로고침했을 때, 깜빡이는 현상과 앱 사용간의 부드러움이 조금 떨어짐, UI 가 제한적
- Native API 를 직접 쓸 수 없어 기기와 직접적인 연동이 어렵다.
- ex. 카메라 직접 접근, 생체 인증
- 웹뷰만으로 구성된 앱은 스토어 심사가 어려울 수 있다.
- 꼼꼼한 정책 확인이 필요 Google의 WebView 및 제휴사 스팸 정책, Apple의 Minimum Functionality 정책
웹뷰의 장점
- 여러 플랫폼에서 개발이 가능 (웹, AOS, IOS)
- 웹과 앱을 한번에 개발하기 때문에 개발 속도가 빠르고, 사용자에게 동일한 UX 제공이 가능
- 배포가 쉽고 빠르다
- 앱의 경우 수정사항이 있을 때, Native 배포 절차에 심사가 포함되어 시간이 오래 걸리고 까다로움
- 웹뷰의 경우에는 바로 배포가 가능
- 웹 → 리액트 네이티브
- onMessage 프로퍼티: React Native의 WebView에서 웹페이지(JavaScript)로부터 메시지를 받을 때 사용
- postMessage 메소드: 웹페이지에서 React Native의 WebView로 메시지를 보낼 때 사용
React Native CLI
- Expo CLI 이전, 리액트 네이티브 팀과 커뮤니티가 제공한 툴
- 기초적인 개발 설정을 제공하지만 추가 구성 설정 필요
- 자바스크립트 코드와 네이티브 기기 소스 코드를 합쳐야 한다면 React Native CLI 가 적합
Expo CLI
- 정리된 앱 개발 워크플로우로서 프로젝트 생성 및 코드 작성과 네이티브 기능 통합이 쉬움
- React Native CLI 보다 훨씬 쉽고 간단하며 언제든 React Native CLI 로 전환 가능
- EAS (Expo Application Services)
- Expo 관리 장치에서 앱을 빌드하고 앱 스토어에 제출하는 프리미엄 서비스
프로젝트 설정하기
# Expo CLI 설치
sudo npm install -g expo-cli
# 원하는 프로젝트로 변경
cd { 원하는 프로젝트 경로 }
# Expo 프로젝트 생성
# 구버전: expo init { 프로젝트 명 }
npx create-expo-app --template {Example}
yarn create expo-app
npm create expo-app
리액트 네이티브 웹 뷰 추가하기
# WebView 라이브러리 설치
yarn add react-native-webview
import { WebView } from 'react-native-webview';
export default function App(){
return (https://moxda.store>" }} />)
}
한계점
- 노치에 가려지는 화면
- 뒤로/앞으로 가기 불가
- 스와이프 불가
- 키보드가 화면을 다 잡아먹는데... 스크롤이 안 되는 현상
웹과 다른 앱 개발에서 필요한 개념
- 네비게이션 (웹에는 라우터가 있지만 앱에는 네비게이션)
- 화면 중첩과 보호
- 조금 더 자세히 알아보면..
- 웹은 앵커 태크 (<a></a>)
- 웹은 URL이 브라우저 히스토리에 스택으로 푸시
- 앱은 네비게이터 (Navigater)
- 네비게이션은 정의한 화면을 렌더링하는 방법을 결정하는 리액트 컴포넌트
- 앱이 화면을 전환하고 탐색 기록을 관리할 수 있는 방법
- 차이점은 스택이 변경될 때 제스쳐와 애니메이션을 제공한다는 것
- 네비게이션 컨테이너
- 탐색 트리를 관리하고 상태를 포함하는 루트 컴포넌트
- 모든 네비게이터 구조는 여기에 래핑
- 화면 구성을 정의하기 위한 스크린 컴포넌트를 자식으로 포함
<NavigationContainer> <Stack.Navigator screenOptions={{ headerShown: false, }} initialRouteName="Login"> <Stack.Screen name="Login" component={Login} /> <Stack.Screen name="Main" component={MainWebView} /> <Stack.Screen name="SignUp" component={SignUpWebView} /> </Stack.Navigator> Stack Drawer BottomTab </NavigationContainer>
- 웹은 앵커 태크 (<a></a>)
- 네비게이션이란?
- 네이티브 기기와 통신
- 권한 획득
- 저장소 차이 (local storage, session storage vs async storage)
- 푸시 알림
- expo-notifications
- 사진 촬영
- 파일 업로드, 다운로드
앱 구현과 기본 설계는 어떻게..?
- 모바일 웹과 앱에서의 컴포넌트를 어떻게 구분해서 제어할까?
- 앱인지 (웹뷰인지) 여부를 판단해서 조건문으로 컴포넌트를 렌더링
- 웹뷰인지 앱인지 여부를 판단하는 방법
- userAgent 활용
const isIos = window.navigator.userAgent.match('iPad') || window.navigator.userAgent.match('iPhone')
- 스크린 넓이로 판단
- 페이지 라우팅은 어떻게 제어할까?
- router 이벤트를 발생시키지 않고 postMessage로 웹뷰에 보내자
- https://ww8007-learn.tistory.com/16
- 로그인 여부에 따라 다른 화면을 보여줄 수 있을까?
- 쿠키, 로컬 스토리지에 저장된 유저 정보를 전송하고 네비게이션을 중첩
- 유저 정보를 어떻게 저장해둘까?
- 리액트 네이티브 저장소 라이브러리를 적용
- https://www.npmjs.com/package/@react-native-async-storage/async-storage
@react-native-async-storage/async-storage
Asynchronous, persistent, key-value storage system for React Native.. Latest version: 2.1.2, last published: 10 days ago. Start using @react-native-async-storage/async-storage in your project by running `npm i @react-native-async-storage/async-storage`. Th
www.npmjs.com
배포 하기
eas build
- 플레이스토어, 앱 스토어에 올리면 끝
- 구글 개발자 계정, 애플 개발자 계정을 각각 등록
- 애셋 준비
- 아이콘, 스크린샷, 안내용 동영상 등
- 참고
- https://velog.io/@nawnoes/Expo로-개발한-React-Native-앱-배포하기-Standalone-앱-빌드
정리
목표는 최소한의 개발, 최대한 빠른 릴리즈
- 화면에 대한 설계
- 각 화면의 연결을 어떻게 관리할 것인지 네비게이션 고려
- 웹, 모바일 웹, 앱을 구분하는 함수를 만들고 웹과 앱이 통신하는 브릿지 작성
- 유저의 사용성을 개선하기 위한 저장소 추가
- 앱이 배포되기 위한 필요 최저한의 네이티브 개발
- 푸시 알림