맨틀 이야기

PWA와 웹앱 푸시 알람 본문

카테고리 없음

PWA와 웹앱 푸시 알람

jbilee 2024. 5. 19. 16:04

리액트를 배우기 시작하면서 만든 내 생애 첫 리액트 프로젝트는 뽀모도로(Pomodoro) 앱이었다. 나도 많은 초보자와 마찬가지로 to-do 리스트 튜토리얼로 리액트를 처음 접했는데, to-do 리스트 구현이 간단하다고 느껴져서 추가적으로 기능을 더해서 실용적인 웹앱을 만들어보고 싶었다.

 

마침 생산성 앱 중에서는 to-do 리스트와 뽀모도로용 타이머를 결합한 앱이 많았어서 뽀모도로 앱을 리액트로 구현해보기로 했다. 타이머를 구현하기 위해 setInterval 함수를 사용했는데, 리액트의 리렌더링으로 인해 setInterval 함수가 중복적으로 호출되는 등의 로직오류로 많이 헤맸던 기억이 있다. 그래도 꾸준히 작업해서 제대로 동작하는 타이머를 만들긴 했는데, 정작 더 중요한 문제는 따로 있었다. 

 

데스크톱과 모바일 웹 환경의 특수한 차이점

반응형으로 만들면서 모바일에서도 내 뽀모도로 앱을 테스트해봤는데, 이때 특이점을 발견했다. 모바일 기기의 화면을 끄고 n분이 지난 후에 다시 켜서 내 앱화면으로 돌어가면 마지막으로 봤던 시간에서 n분이 깎인 시간이 남은 시간이어야 하는데, 화면을 끈 시점의 남은 시간부터 카운트다운이 재개되고 있던 것이다. 중간에 흘렀던 n분은 타이머의 남은 시간에서 차감되지 않았다.

 

알고보니 데스크톱과 다르게 모바일 웹브라우저는 브라우저 앱이 최소화되거나 기기의 화면이 꺼진 상태에서 setTimeout, setInterval 등의 특정 비동기 함수를 수행할 수 없는 단점이 있었다.

 

데스크톱에서는 앱화면의 visibility 상태가 바뀌어도 setInterval이 계속 돌아가니 문제가 없지만, 모바일 사용자는 visibility 상태가 바뀌는 사이사이에 시간의 흐름이 트랙킹되지 않으니 썩 실용적인 타이머 앱은 아니었다. 다행히 모바일에서도 웹 API의 visibilitychange 이벤트를 핸들링할 수 있어서 visibility에 변화가 있을 때마다 Date.now() 값을 기준으로 흐른 n 시간을 계산하는 차선책을 적용했다. 문제는 화면이 꺼진 상태에서 타이머의 남은 시간이 0이 됐을 때, 이를 사용자에게 따로 알릴 수 있어야 한다는 것이었다. 어떻게 이 문제를 해결할지 알아보다가 PWA에 대해 알게 됐다.

 

PWA란?

Progressive Web App(PWA)은 웹이 아닌 플랫폼에서 네이티브 앱(iOS 앱, 안드로이드 앱)처럼 동작하는 웹앱을 말한다. 앱스토어에서 다운받지 않아도 모바일 기기에 앱처럼 설치할 수 있고, 웹앱이기 때문에 Kotlin이나 Swift와 같은 플랫폼 앱개발 전용 언어를 따로 배울 필요가 없다.

 

PWA의 가장 큰 장점은 네이티브 앱이 아니어도 모바일 기기로 푸시 알람을 발송할 수 있다는 점이다. OS에서 제공하는 기능을 네이티브 앱처럼 모두 활용할 수는 없지만, 결정적으로 푸시 알람 이용이 가능한데다가 대충 봐서는 큰 차이를 못느낄 정도로 네이티브 앱처럼 동작하도록 만들어졌다.

 

일반 웹앱을 PWA 형태로 제공하려면 manifest 파일을 작성하고 service worker를 설치해야 된다. JSON으로 작성하는 manifest 파일은 내 웹앱이 모바일 기기에 설치된다면 앱 이름이 어떻게 표기될지, 앱 아이콘은 어떤 이미지를 쓸지, 앱을 실행하면 웹앱의 어느 페이지부터 띄우는지 같은 설정을 적을 수 있는 파일이다.

 

PWA를 만들 때 필요한 최소한의 정보:

{
  "$schema": "https://json.schemastore.org/web-manifest-combined.json",
  "display": "standalone",
  "start_url": "/",
  "name": "Palmodoro",
  "short_name": "Palmodoro",
  "icons": [
    {
      "src": "/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

 

PWA 설치 방법

PWA는 실제 앱이 아니라 웹앱에 manifest 파일만 추가한 앱이기 때문에 앱스토어에 올라가지 않는다. 일반 유저가 PWA를 모바일 기기에 설치하려면 모바일 브라우저에서 해당 웹앱 페이지를 "홈화면에 추가"하면 된다.

 

PWA가 아니라면 그냥 북마크를 홈화면에 추가하게 되기 때문에 아이콘을 탭했을 때 브라우저로 넘어가지만, 만약 PWA를 지원하는 웹앱이었다면 홈화면에서 아이콘을 눌렀을 때 브라우저를 실행하는 대신 네이티브 앱 형식으로 띄우게 된다.

 

 

웹에는 service worker를 통해 모바일 푸시 알람을 보내주는 push API가 있다. 다만 내가 당장 배워서 구현하기엔 부담스러운 학습량인거 같아서 써드파티 서비스를 하나 골라 사용해보기로 했다. 테스트 레포에서 따로 먼저 실험해보고, 그 결과는 나중에 더 자세히 기록해볼 생각이다.