리액트 네이티브 앱 개발 후기(4)
안녕하세요, 리액트 네이티브 앱 개발 후기를 쓰고있는 식물키우는개발자 입니다.
빨리 써야지 써야지 했었는데 매일 집에오면 쓰러져 잠들기 바빴어서.. 이제야 틈나서 써보네요.
(사실 어제밤에 이거 쓰다가 1시간 가량 쓰던거 크롬 OOME로 다날아간건 안비밀ㅠㅠㅠ 맴찢하고 오늘 다시 씁니다. 구글드라이브에 쓰고 옮김 ㅎㅎ)
전편 :
1편 - react native로 앱을 만들게 된 계기와 간략한 소회
2편 - react native 프로젝트 구성하기까지 겪은 일들
3편 - react native 세계의 애증 expo의 장점과 단점
그리고 마지막으로 서드파티 라이브러리 커스터마이징, 네이티브 설정 삽질기, 현재 앱의 결과물이랑 남은 과제들 정도 공유드려보려고 합니다.
같은 내용을 두번째 쓰려니 감회가 새롭네요ㅎㅎ
서드파티 라이브러리는 대부분 갖다 쓰기만 하는데, 가아아끔 라이브러이에서 제공하는 커스터마이징 영역을 벗어나게 커스터마이징이 필요한 경우가 있습니다.
개발자가 원래 자기만 쓰려고 만들었다가 오픈소스로 풀었다거나,
크나큰 꿈을 가지고 만들다가 도중에 알 수 없는 사유로 개발을 중단했다거나,
아직 다 완성하기 전이라서 정식버전이 나오지도 않았지만 대체재가 없다거나
한 경우들입니다.
제 경우의 대표적인 예는 react-native-masonry-list 라이브러리였습니다.
masonry list라고 하면 벽돌모양 레이아웃을 말하는데요,
react native에서는 기본적으로 여러 column 갯수의 리스트를 지원하기는 하지만 표 형식으로 제공되어서
masonry list같은 레이아웃은 지원하지 않습니다.
그림으로 말씀드리자면


왼쪽이 react native에서 기본으로 제공하는 flatlist를 사용한거고,
양옆의 데이터 요소들의 크기가 다르면 큰쪽으로 각각이 맞춰져서 틀에 짜여진 바둑판식이 됩니다.
근데 대부분의 서비스에서 이렇게 여백이 생기는게 바람직한 모습은 아니죠.
오른쪽과 같이 여백없이 촘촘하게 짜여진 모습이 더 깔끔하고 보기 좋습니다.
이런걸 가능하게 해주는게 react-native-masonry-list 라이브러리인데요,
(아, 참고로 제가 사용한 라이브러리는 LueHang 님의 react-native-masonry-list 라이브러리입니다.
지금 검색해보니 같은 이름의 라이브러리를 다른 분이 개발한 것도 나오네요.)
여기에 몇가지 문제가 있었습니다.
1. 동적으로 데이터 갯수를 변경해야 하는 일이 있는데, N(>0)개에서 0개로 바꾸는 경우 변경이 인식되지 않아서 리스트에 반영되지 않음
- 제 경우 리스트 상단에 탭 버튼을 두고 탭을 이동하면 데이터만 변경해서 탭 이동을 표시하려고 했습니다.
한 화면에 여러 리스트를 두지 않으려고 했거든요. 근데 탭 중에 데이터가 없는 탭(로그인 안한 경우 등)도 있어서.. 이런경우 그 전 탭의 리스트 내용이 그대로 남아있게되는 버그가 있었습니다.
2. 애니메이션 추가가 안됨
- 이 라이브러리의 경우 최상단 컴포넌트 뿐만 아니라 그 하위 세부 컴포넌트에도 Animated 설정을 적용해야 제대로 애니메이션이 동작해서, 내부를 직접 수정할 수밖에 없었습니다.
- 이런건 말해도 반영해주지 않겠죠.. 따흐흑
3. 크기와 비율이 다양한 이미지를 표시할 때 비율을 특정 값(N개) 중 하나로만 표시하게 하기
단순히 가로폭만 맞추고 원래의 이미지 비율대로 표시하게 했더니 기이이일쭉한 이미지를 올리게되면 화면 하나를 다 차지해버리더라구요. 그래서 제한을 두는 방법을 생각했는데, 비율을 몇 개 중에서 가장 가까운 비율로 골라서 표시하도록 하는 요구사항이 있었습니다.
4. 이미지 로딩에 실패하는 경우에 대한 조치
디폴트이미지를 보여주게 해야하는데 그게 안됐습니다.(fallback)
5. 그 외 하위 세부요소에 특정 props 전달이 추가로 필요함
내부에 flatlist가 있는데 그 flatlist에 추가로 세팅해줘야 하는 설정이 있었고, 그부분까지 커스터마이징이 되어있지는 않았습니다.
react-native-masonry-list 이외에도 3~4개정도의 라이브러리를 더 커스터마이징 했는데요,
다행히도 react-native-masonry-list는 pure js 라이브러리였지만
다른것들은 네이티브 소스도 있었기때문에.. 애를 좀 먹었습니다.
예를들어 image picker.. react-native에서 기본으로 제공하는 이미지 피커는 없고(community에서 만든 것이 있긴 한데, 너무 기능이 제한적이었습니다) expo-image-picker역시 여러 개의 이미지 선택이 제공되지 않았습니다.
이미지 피커의 경우 물론 expo-multiple-image-picker같은 라이브러리도 있긴했지만, 제공하는 기능이나 코드가 좀… 제 마음에 들지는 않았습니다. 제가 개발하는 서비스에서 원했던 기능은
이미지 다중선택이 되면서
선택한 이미지의 순서(인덱스)가 표시되고
이미지 선택하는 화면에서 사진촬영하는 기능을 포함하고
취소, 선택완료하는 버튼의 위치와 폰트 등을 조정
할수 있어야했는데 이걸 다 만족하는 라이브러리는 없었습니다. 제일 많이 사용하는 react-native-image-crop-picker는 여기에서 2, 4 등이 없는 식입니다.
그래서.. 하나를 골라서 수정하는데 어쩔 수 없이 네이티브(특히 objective-c 코드.. 문법부터가 이해하기가 너무 어려웠습니다.
대괄호의 의미를 알게된것도 2주정도 걸렸습니다 ㅠㅠ)
image picker 수정하는데만 거의 한 달은 걸린 것 같습니다. 물론 한번에 뙇 한건 아니고 베이스 라이브러리 선정하고, 아이폰 먼저 하고, 안드로이드 나중에 해서 순차적으로 배포했는데 지금 생각해도 너무 힘들었네요.
이게 지금의 이미지 피커 모습입니다.

사진찍는 영역의 배경색과 아이콘, 선택한 이미지의 표시나 각 버튼 위치 등등 다 수정해줬습니다. 처음하는거라 조잡하게 하긴 했는데 나중에 수정...해야죠 ㅎㅎ
나중에는 네이티브 영역(swift나 kotlin) 언어 공부 무조건 해야겠다..는 생각이 들었습니다 ㅠㅠ 너무 헤맸어요 엉엉
다음은 네이티브 설정입니다.
지난번에 언급한 것처럼 저는 expo에서 eject를 했는데,
그 이전에는 expo에서 모든 네이티브 workspace를 알아서 자동으로 생성해줬습니다.
근데 eject를 하고 나면 네이티브 workspace는 스스로 구성하고 관리해야합니다.
그래도 제로베이스에서부터 구성해나가는건 아니어서 다행이었지만,
처음 eject하고 나서도 또 무수한 삽질이 들어갑니다.(이쯤되면 당연한거같네요)
이왕 eject 할거라면, 그래도 최대한 바꿀꺼 다 바꾸고 미리 할수있는거 다 하고난 다음에 eject하는걸 추천드립니다.
저의 경우 eject하고 나서 서비스 이름 자체가 바껴버렸습니다.ㅎㅎㅎㅎ
이름 바뀌고, 이름에 따라 패키지 이름도 바꿨는데
특히!!! 이 패키지 이름 바꾸는게 상상초월이었습니다ㅋㅋㅋㅋㅋㅋ 하 지금 생각하면 웃음만 나네요
아무리 바꿔도 바꿔도 뭐가 계속 남아있고
IDE에서 일괄적으로 바꾸게 했더니 프로젝트 구조가 다 꼬여버려서(바보같이 이전에 패키지 이름에 “app”을 넣었더니 멍청한 IDE가 app 들어간 폴더 이름을 다 바꿔놓는 대참사가) 다 롤백하고 다시하고..
끔찍합니다.
여기에 ios의 경우에는 패키지 이름 뿐만 아니라 코드 사이닝도 뭔가 꼬여버려서,
디버깅용 앱을 usb연결해서 실제 아이폰에 설치하려고만 하면 계속 오류가 나서 진짜 막막했습니다.
근데 더 큰 문제는 이 오류가 코드 사이닝 문제라고 알려주지도 않았죠.
“그냥 설치할 수 없다” 라고만 나왔어요ㅎㅎㅎ
이거 고칠려고 구글링을 얼마나 했는지 모르겠네요. 이 문제 고치려고 하다하다 안돼서 나중에는 testflight으로 앱 올려서 실제 기기에서 테스트하기도 했습니다.
(참고로 이 문제의 원인은 ios workspace 내에 같은 설정을 해주는 부분이 중복으로 너무 많이 있어서 였습니다.
code signing 하는 부분이 거의 3~4군데였는데, 그중에 몇군데를 바꾸기 전 설정상태로 남겨놓아서(정확히는 있는지도 몰라서) 발생한 문제였습니다.)
그렇다고 android는 평화로웠냐? 그건 당연히 아니죠. 지금도 확실하게 느끼는거지만 react-native는 ios에는 상당히 최적화돼있지만 android는 젬병인것 같습니다.
똑같은 react-native project로 만들어진 앱인데
ios는 상당히 매끄럽고 예쁘게 떨어지는데
안드로이드만 가면 느리고 버벅대고 끊기고 난리도 아니었습니다.
이 문제때문에 최적화 작업을 상당히 많이 거쳤죠.
그리고 Hermes! hermes 엔진 적용하고 나니 기존보다 약 10~15%정도 (체감상) 빨라졌습니다.
물론 엔진 바꾸면서 바로 짠! 하고 된건 아니고 약간 헤매긴 했지만, hermes 다큐먼트 보고 하니 수월하게 성공했습니다.
이 글을 보시는 분이 react-native로 처음 앱 만드신다면 처음부터 hermes 적용하고 시작하시는걸 추천드립니다.
아 또 안드로이드는 gradle로 디펜던시 관리하다보니.. 라이브러리 버전충돌나면 골치아픕니다.
저의 경우 app.compat? 이라는 구글에서 제공하는 라이브러리가 디펜던시 라이브러리마다 버전이 달라서 hermes 적용할 때 삽질을 좀 했습니다.
최소 버전이 올라가는거 같더라구요.
여튼 react-native로 개발을 한다고 아예 네이티브 영역을 건드리지 않아도 되는 것은 아니고, “최소한”은 할 줄 알아야한다… (그리고 누구도 알려주지 않는다ㅜㅜ)가 결론입니다.
아.. 이게 원래 한번에 다 쓰려고했는데 이미지가 커서 그런지 다 안올라가네요 ㅠㅠ 부득이하게 한번 더 잘라야겠습니다 ㅠ