2020. 3. 8.

BPM Tapper를 PWA로 만들어보았다

PWA를 네이티브 앱처럼 보이게 만들어보려고 했습니다만...


그러니까... 종종 디제잉을 하는데요, 보통은 다들 CDJ를 쓰니까 상관 없는데 가끔 바이닐 쓰시는 분 다음 순서로 들어갈 때라던지... BPM을 확인해서 맞춰서 이어가야 할 때가 있습니다. 물론 딜레이/에코 걸고 끊고 갈 수 있지만 그러면 간지가 안나니까요. 그럴 때 BPM Tapper앱을 쓰는데, 디자인이 맘에 드는 게 없어서 걍 PWA로 만들어보았습니다.

일단 완성된 앱은 아래 링크에서 확인할 수 있습니다. 이름은 Bipi!(BPM이니까...)입니다.

'홈 화면에 추가'등을 이용해 모바일 디바이스에 설치할 수 있고, 화면 아무곳을 탭하면 BPM을 계산해서 보여줍니다. 스와이프를 하거나 4초간 입력이 없으면 0으로 리셋됩니다.

해보고 싶었던 것들

PWA로 만들면서 중요하게 생각했던 것들은 아래와 같습니다.

  • 오프라인에서 작동.
  • 모바일 디바이스에 설치하면 앱 아이콘이 표시.
  • 앱아이콘을 터치해서 실행하면 브라우저로 이동하는 게 아니라 스탠드얼론으로 실행.

다시 말해, 네이티브앱 경험에 최대한 가깝게 만들어보고 싶었는데요, 페이지 이동도 없고하니 네비게이션 관련 이슈가 생길 염려도 없고...

1. 오프라인에서 동작하게 만들기

서비스워커를 설정해주면 됩니다. 따로 한 건 없고 create-react-app에서 만들어주는 index.tsx의 맨 마지막 줄을 바꿔주기만 했다.

...
- serviceWorker.unregister()
+ serviceWorker.register()
...
...
- serviceWorker.unregister()
+ serviceWorker.register()
...

2. 앱 아이콘 추가하기

여기서부턴 manifest.json에 설정을 추가하면 됩니다. manifest.json에서 앱아이콘을 설정하는 부분은 "icons" array.

{
...
+    "icons": [
+        {
+            "src": "favicon.ico",
+            "sizes": "64x64 32x32 24x24 16x16",
+            "type": "image/x-icon"
+        },
+        {
+            "src": "logo192.png",
+            "type": "image/png",
+            "sizes": "192x192"
+        },
+        {
+            "src": "logo512.png",
+            "type": "image/png",
+            "sizes": "512x512"
+        }
+    ],
...
}
{
...
+    "icons": [
+        {
+            "src": "favicon.ico",
+            "sizes": "64x64 32x32 24x24 16x16",
+            "type": "image/x-icon"
+        },
+        {
+            "src": "logo192.png",
+            "type": "image/png",
+            "sizes": "192x192"
+        },
+        {
+            "src": "logo512.png",
+            "type": "image/png",
+            "sizes": "512x512"
+        }
+    ],
...
}

3. 스탠드얼론 앱으로 실행되게 만들기

manifest.json에서 앱 바디가 어떻게 보이느냐를 설정하는 부분은 "display"입니다. 아래와 같이 standalone으로 설정했다.

{
...
+    "display": "standalone",
...
}
{
...
+    "display": "standalone",
...
}

display의 설정값들과 설정시 화면 동작은 아래와 같았다.

프로퍼티데스크탑 브라우저iOSfallback
fullscreen스탠드얼론 + status/navigation 바 표시 안함스탠드얼론으로 열림standalone
standalone앱으로 설치 가능 + 약간의 브라우저 기능스탠드얼론으로 열림minimal-ui
minimal-ui앱으로 설치 가능 + 메뉴바에 약간의 ui 컨트롤(백버튼 등)이 있음..이라고 되어있는데 디폴트 브라우저에서 열림browser
browser디폴트 브라우저에서 열림같음-

4. 상태바 스타일링되게 하기

안드로이드/크롬에선 기본적으로 특별히 설정하지 않아도 그냥 되지만, iOS 기기는 따로 설정을 해주어야 합니다. index.html<head> 영역에 아래 코드를 추가합니다.

+    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
+    <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />

역시 정리해 본 apple-mobile-web-app-status-bar-style의 설정값들과 설정시 화면 동작.

프로퍼티설정시 화면 동작
default상단에 상태바가 흰색 배경에 검은색 글자로 표시.
black상단에 상태바가 검은색 배경에 흰색 글자로 표시.
black-translucent상태바가 웹앱 배경색 배경에 흰색 텍스트로 표시.

그리하여..

완성된 앱은 아래와 같이 동작합니다.

Bipi! Launch Screen Capture

그런데..

해놓고 보니 뭔가 흉내내기 하는 것 같고 동작에 이런저런 답답합이 있어 내친김에 iOS 네이티브앱(SwiftUI를 써서)으로 다시 만들어보았습니다(관련해선 나중에 써보려고 함).

참고

Edit (2023. 5. 14 업데이트)

  • 이게 벌써 3년이 되었다니...
  • 글고보니 언젠가 무려 react native for web으로 바꿨었네요.
  • 요즘은 vite+shadcn/ui 등으로 스택을 모더나이즈(...)하고 이런저런 설정도 할 수 있도록 v2를 만들어보고 있습니다.