알람 앱은 그냥 만들어도 귀찮지만 리액트 네이티브로 만들면 더 귀찮다⏰ Part1 — 개요, TimePicker

안드로이드와 iOS에서 알람 앱을 만드는 방법과 그 위에 리액트 네이티브를 끼얹는 개발기

MJ Studio
MJ Studio

--

Content

Part 1 — 개요, TimePicker← Here 🤚

Part 2 — 안드로이드

Part 3 — iOS

이 글은 무엇인가?

당신이 어플리케이션의 알람 기능을 구현하기 위해 인터넷을 찾아 헤매는 안드로이드, iOS 혹은 불운하게도 React Native, Flutter의 개발자라면 안타깝게도 이 글은 많은 도움이 되지 않을 것이다.

왜냐하면 이 글은 내가 다니는 회사에서 필요하대서 만들어준 React Native 앱의 알람 기능을 구현하기까지의 개발 과정이 빨리 끝난 관계로 심심해서 쓴 글이기 때문이다.

어느 튜토리얼들만큼 친절하지 않고 원하는 기능과 괴리가 있을 수 있으며 무엇보다 독자의 수준을 고려하지 않는다.

그래도 어떠한 insight를 얻고 싶다면 좋은 시작지가 될지도 모른다.

각 모듈들이 독립적이라면 독립적일 수 있어 몇 가지 Part로 글을 분리했다.

일단 만든 기능은 다음과 같다.

원하는 시간과 요일을 설정하면 해당 날짜의 해당 시간에 주기적으로 Local notification을 쏘고 한 번 작동할 때 1분 정도 동안 5초 간격으로 계속 push message가 쌓이는 기능이다.

또한 어플리케이션의 현재 상태(Foreground, Background, Exit) 등에 대하여 알람을 받은 이벤트, 클릭한 이벤트 등을 잡아내 React Native 단에서 Deeplink 로써 원하는 Behavior로 처리되게 연결도 되어 있지만 그 부분까지는 자세히 다루진 말자.

순수히 앱 외부와의 통신 없이 OS의 API들이나 몇 가지 라이브러리에 섞여서 동작된다.

이제 본격적으로 개발기를 작성하기에 앞서 개발이 급한 개발자들은 빠르게 insight를 얻어 갈 수 있도록 TL;DR 을 남겨둔다.

TL;DR — 이 글을 100% 이해하기 위해 필요한 사전 지식

  • Typescript, Kotlin, Swift, Objective-C(a little)
  • React Native — Native Module, Native Component, Linking API
  • Android — Android Architecture Component(Lifecycle, WorkManager), PendingIntent, Intent, AlarmManager(Not used), BroadcastReceiver(Not used)
  • iOS — UserNotification API

운 좋게도 여기까지만 보고도 어떻게 만들었는지 감이 온다면 사실 그 뒤 내용이 별 필요가 없을 수도 있다.

Part 1엔 가장 심플한 시간을 선택하는 모듈을 구현한 방법부터 수록되었다.

알람 기능은 왜 귀찮은가?

React Native를 개발하고 있는데 갑자기 알람 기능을 개발하는 업무가 주어졌다고 하자. 대부분은 1. 싫거나 2. 귀찮거나 3. 자신만만하게 할 수 있다고 하거나 셋 중 하나일 것이다.

3번이 나오는 경우는 주로 이전에 이미 이런 기능을 솜씨 좋게 개발해 본 사람이거나 아직 사안의 심각성을 깨닫지 못했을 수도 있고, 나 같은 경우는 1.7 정도였다.

운 좋게도 안드로이드나 iOS의 네이티브 개발자라면 꽤나 수월할 수도 있지만 React Native의 개발자라면 갈 길이 멀다.

React Native 개발자라고 가정하고 만약 앱에 알람 기능이 필요하지 않다고 논리적으로 설명할 수 있는 커뮤니케이션 능력을 겸비하고 있거나 React Native에선 그 기능을 구현하는 게 불가능하다고 연역적으로 설득하며 이 글을 재직기간 동안 팀원들이 못 보게 할 수 있다면 개발을 안 해도 될지도 모른다.

그렇지 않다면 앞서 말했듯이 이 글은 개발의 좋은 entry point가 되어 줄 수도 있다.

서론이 길었는데 알람 기능이 귀찮은 이유는 안드로이드와 iOS에 대한 사전 지식 없이도 60fps로 쌩쌩 돌아가는 앱을 누구나 만들 수 있다며 과대광고하던 메타(구 페이스북)에게 배신감을 느낄 수 있을 정도로 Native code와 API들을 과도하게 사용해야 하는 기능이기 때문이다.

물론 잘 만들어진 React Native의 알람 라이브러리들이 있을 지도 모르지만, 그간의 경험으로 봤을 때 그 라이브러리가 우리가 원하는 기능을 100% 구현해두었으며 생각한 대로 동작할 수 있을 것이란 기대는 하지 않는 게 좋다. 사실 뭐가 있는지 찾아보지도 않아서 잘 모른다.

그것들로 시간 낭비를 하느니 Android Studio나 Xcode 둘 중에 마음에 드는 걸 아무거나 먼저 켜서 구현을 시작하는 게 정신 건강에 이롭다.

Feature 1 — Android TimePicker

일단 알람을 구현하기 위해서는 사용자가 시간을 선택할 수 있어야 한다.

놀랍게도 React Native는 PickerPicker는 죄다 Core에서는 deprecated 되어 커뮤니티의 관리를 받고 있는데, 여기서부터 애로사항이 꽃 필 수 있다.

이제 그 커뮤니티의 라이브러리를 가보면 iOS는 우리가 흔히 아는 spinner 모양의 TimePicker UI를 제공하지만(나도 iOS는 이걸 그대로 썼다.) 안드로이드는 얄짤없이 다음과 같이 2개 중 하나를 골라야 한다.

운 좋게도 앱의 UI가 Material design의 guideline을 충실히 이행하여 위 UI들이 이색적이지 않다면 그냥 쓸 수도 있지만, 그게 안되면 난관에 봉착하게 된다.

여하튼 그래서 나는 이걸 Android의 다른 library를 React Native의 Native Component로 포팅 했다.

AigeStudio/WheelPicker 라이브러리는 마지막 커밋이 3년 전인데, React Native 였으면 이걸 그대로 쓰는 것은 자살행위지만 안드로이드의 세계에서 이 정도면 양호하다.

이 라이브러리는 TimePicker 라기보다는 아이템들을 Wheel로 돌릴 수 있게 Picker를 구현해둔 것이다. 이 라이브러리는 감사하게도 WheelPicker를 기반으로 몇 가지 위젯들을 만들어두었는데, 날짜를 고를 수 있거나, 연도를 고를 수 있거나 달을 고를 수 있거나 장소를 고를 수 있거나 하는 위젯들이다.

그렇다. 공교롭게도 시간을 고를 수 있는 위젯은 3년 전에 바빠서 못 만들어 둔 것 같으니까 직접 만들면 된다.

TimePicker 라는 녀석을 당신이 Java나 Kotlin에 상당한 조예가 있다면 안드로이드단에서 코드를 구현해서 그걸 Native Component로 만들어도 되지만, 나 같은 경우는 WheelPicker만 대충 포팅 해서 TimePicker라는 컴포넌트는 React Native 단에서 구현했다.

간단히 WheelPicker를 담고 있는 ViewManager를 만들어서 몇 가지 조절할 Props들만 RN에서 설정할 수 있게 빼주고 아이템이 선택될 때 이벤트를 구독하고 있다가 그것도 Props로 들어온 콜백 함수로 전송해 주면 된다.

대략 다음과 같은 식인데, 혹시나 독자 중에 RN의 Native Module/Component를 어떻게 만드는지 알고 싶은 분이 계시다면 RN 공식 문서 가서 읽거나 예전에 놀랍게도 이런 날이 올 줄 알고 내가 미리 만들어둔 샘플 라이브러리를 참고할 수 있다.

이제 이걸 RN 단에서 타입스크립트로 하나의 컴포넌트로 만들어주기만 하면 된다. 이건 중요하지 않아 생략한다.

지금 보니 이름을 잘못 지었다. WheelPicker라고 하면 되는데 굳이 NumberPicker라고 명명했다.

이제 NumberPicker를 세 개를 써서 TimePicker를 RN 컴포넌트로 만들어주면 된다.

구현은 다행스럽게도 leap year 따위의 도메인 지식도 고려해야 하는 DatePicker가 아니라 TimePicker이기 때문에 간단하다. 시간은 [0, 24), 분은 [0, 60) 으로 잡고 오전/오후는 시간에 적절히 two-way binding 같이 구현해 주면 된다.

What’s the next?

이제 1단계인 안드로이드에서의 깔끔한 TimePicker까지 구현했으므로 다음 Part들엔 실제로 알림 들을 각 OS에서 어떻게 구현해두었는지 파헤쳐 보도록 하자.

--

--