iOS 및 Android에서 PWA 지원하기
Last updated: May 15, 2023
이번에 버스하냥 서비스를 리뉴얼 하면서 PWA를 더 잘 지원하기 위한 노력들을 적어보고자 한다.
PWA란?
PWA란 Progressive Web App의 줄임말이다.
Web 환경에서의 서비스는 상대적으로 발견되기 쉽고, 다른 사람들에게 링크 하나로 쉽게 공유될 수 있다는 특징이 있다.
반면 Native 앱 같은 경우에는 시스템에 설치하는 방식이라 사용자 경험을 극대화할 수 있고, 앱 서랍에서 앱 아이콘을 클릭해서 쉽게 접근할 수 있다는 특징이 있다. 또한 Native는 오프라인에서도 사용이 가능하다.
PWA는 Native의 이러한 장점들을 Web 환경에서 유사하게 지원하게끔 만들어준다.
버스하냥은 학교 셔틀버스 시간표를 간단하게 보여주는 서비스로, 사용자들이 보다 쉽게 접근할 수 있는 Web으로 서비스를 제작하게 되었고, 매번 사이트를 찾아 직접 접속하는 귀찮음을 줄이기 위해 PWA를 지원하게 되었다.
PWA의 자세한 정보는 여기를 확인하자.
PWA 지원 조건
Web 서비스가 PWA를 지원하기 위해서는 다음과 같은 조건이 필요하다.
- Web manifest 파일
- HTTPS로 서비스가 제공될 것
- App으로 표시될 때의 아이콘
- Service Worker
Manifest
Manifest 파일은 PWA를 설치하기 위한 정보들이 포함되어 있는 파일이다. 파일에는 PWA 이름, PWA 설명, 테마 색상, PWA 메인 화면 URL, 아이콘 크기 및 경로 등이 포함되어 있다.
{
"name": "버스하냥",
"short_name": "버스하냥",
"icons": [
{
"src": "icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#ffffff",
"background_color": "#ffffff",
"start_url": "/",
"display": "standalone"
}
Key 값을 보면 대충 무슨 역할을 하는 값들이 포함되어 있는지 알 수 있다. 하지만, 이번 버스하냥 서비스는 Vite
를 통해 제작되었고, Vite
에서 manifest 파일을 자동으로 생성해 주는 vite-plugin-pwa
플러그인을 사용하여 제작하였다.
import react from '@vitejs/plugin-react'
import { defineConfig } from 'vite'
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
VitePWA({
// PWA setting
manifest: {
theme_color: '#ffffff',
background_color: '#ffffff',
display: 'standalone',
scope: '/',
start_url: '/',
name: '버스하냥',
short_name: '버스하냥',
icons: [
{
src: 'image/pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'any',
},
{
src: 'image/pwa-maskable-192x192.png',
sizes: '192x192',
type: 'image/png',
purpose: 'maskable',
},
{
src: 'image/pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any',
},
{
src: 'image/pwa-maskable-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'maskable',
},
],
},
}),
],
})
manifest 파일을 수동으로 만드는 거와 넣는 값에는 큰 차이가 없다. 하지만 수동으로 만들게 되면 빌드 하는 과정에서 따로 manifest 파일을 빌드 root 디렉토리에 넣어주고 배포하는 과정이 필요한데 플러그인을 쓰면 해당 과정이 하나 줄어든다는 차이가 있다.
HTTPS
HTTPS는 HTTP 프로토콜에서 TLS/SSL을 이용한 암호화와 검증이 추가된 프로토콜이다. 그냥 HTTP를 사용하게 되면 제3자가 어떤 데이터가 오가고 어떤 사이트를 접속했는지 알 수 있고, 데이터를 중간에 수정해서 보낼 수도 있기에(MITM Attack) 보안에 취약하다.
버스하냥은 대형 서비스가 아닐뿐더러, 유지 보수를 할 수 있는 인원이 많지 않기에 인증서 갱신 및 발급을 신경 쓰지 않아도 되는 서비스를 이용하고자 했다. 기존에는 GCP App Engine에 커스텀 도메인을 연결하여 서비스를 배포하였으나, 트래픽이 많아지면서 Free Tier를 사용할 수 없게 되어 서버 비용이 지속적으로 나가고 있었다. 이번에 이를 보완하고자 Cloudflare에서 새로 시작한 서비스인 Cloudflare Pages를 이용하였다. 해당 서비스의 최대 장점은 무료티어에서도 사이트, 요청수, 대역폭이 무제한이라는 것이다. 또한 서버가 Cloudflare쪽에 있으면 Cloudflare의 가호도 받을 수 있다. 😆
Icon
아이콘은 기존 PWA 앱을 설치했을 시 앱 서랍에 표시될 앱 아이콘이다. 해당 아이콘은 기존 서비스와 동일하게 대외협력처 승인하에 학교 마스코트인 하냥이의 응용동작을 이용하여 제작하였다.
Service Worker
Service Worker는 PWA와 브라우저 간에 프록시 서버와 같은 역할을 한다. 오프라인 지원, 푸시 알림 지원, 웹 페이지 파일 캐싱을 전부 여기서 담당하게 된다.
Service Worker는 추후의 UX 최적화 글에서 세부적으로 설명할 예정이지만, 간단히 설명하자면 Manifest와 마찬가지로 Vite
의 vite-plugin-pwa
에서 설정이 가능하다. 빌드 시 Service Worker 자바스크립트 파일을 자동으로 생성하고, 디렉토리에 자동으로 들어간다.
다크모드와 상단바
이번 리뉴얼 서비스에서 가장 크게 바뀐 점 중에 하나이다. 기존의 PWA에서도 다크 모드를 지원했지만, PWA와 웹에서 상단 바 색깔을 동적으로 바꾸는 API는 없다. 따라서 다크 모드와 라이트 모드를 쓰게 되면 색깔 차이가 나서 이질감이 든다.

그 어디에서도 공식적으로 지원하는 기능이 아니었기에, 직접 구현하기로 하였다.
우선 상단 바 색깔 지원을 어떻게 하는지부터 알아보았다.

Meta tag로 theme-color
값을 지정해 주면 상단 바 및 주변 색깔들을 바꾸어 준다고 한다. (링크)
사이트 로딩 시 <head>
태그에서 스크립트를 실행하여 다크 모드인지 라이트 모드인지 파악한 뒤, 해당 모드에 맞게 theme-color
값을 바꿔주는 방법을 시도하였다.
let pageTheme = window.localStorage.getItem('theme')
if (pageTheme !== null) {
const barStyle = document.querySelector('meta[name=theme-color]')
if (barStyle !== null) {
if (pageTheme === 'light') {
barStyle.setAttribute('content', '#FFFFFF')
// For iOS
document.body.className = ''
document.body.style.backgroundColor = '#FFFFFF'
}
if (pageTheme === 'dark') {
barStyle.setAttribute('content', '#27272A')
// For iOS
document.body.className = 'dark'
document.body.style.backgroundColor = '#27272A'
}
}
}
해당 스크립트를 넣고 PWA 실행 결과, 다크/라이트 모드 변경 시 상단 바 색깔도 바뀜을 확인할 수 있었다! iOS에서도 테스트한 결과, 정상적으로 작동하였다.

해당 기능을 적용하고 나니, 서비스의 UI 적인 부분이 개선되어서 사용자들에게 더 나은 서비스를 제공할 수 있게 되었다. 다음 게시글에서는 버스하냥 서비스의 UX를 어떻게 개선했는지에 대해 이야기해 보고자 한다.