1. 프로젝트 간단요약
✅ 프로젝트 개요
- 이름
- 답지, DapJi
- 목적
- 클라이밍을 좋아하는 클라이머들이 좀 더 재밌게 취미 생활을 즐길 수 있도록 각 암장의 문제풀이를 공유하는 플랫폼
👀 1차. Web - Next.js
- 웹뷰를 통해 앱 제작을 기획하고 프로젝트 진행
- 좀 더 네이티브스러운 기능을 사용하기 위해 하이브리드 앱으로 전환
- 웹을 관리자용으로 사용 할 예정, 또는 링크공유 적용 할 예정
👀 2차. App - EXPO
react-native를 기반으로한 expo 사용
✅ 주요 기능
- 바텀 탭을 사용해 4개의 주 페이지로 구성, 각 페이지는 스크롤이 가능하도록 FlatList를 사용한 무한스크롤 기능으로 구현 ,
- 소셜 로그인
- Apple Login ****expo expo-apple-authentication 을 사용해 구현, 앱스토어 배포시 필수,
- Kakao Login react-native-seoul/kakao-login을 사용해 구현
- 일반 로그인 세션을 사용해 유저 정보를 확인하고 로그인 유지
- 답지 동영상
- expo - av 라이브러리 사용,
- 동영상의 썸네일 추출 후 유저 프로필 페이지에 있는 유저가 올린 답지 기능에 적용,
- 댓글 및 좋아요, 암장 즐겨찾기
- 게시물이나 각 영상마다 댓글, 좋아요 기능
- 선호하는 암장을 즐겨찾기 할 수 있음.
✅ 주요 기술 스택
- 프론트엔드
- Web
- Next.js
폴더 중심으로 더욱 체계적인 도메인 생성 가능, VERCEL을 사용한 편리한 배포, SSR을 사용해 초기 빠른 로딩속도, 뷰포트 크기에 따라 이미지를 자동으로 조정하는 Image컴포넌트를 사용한 이미지 최적화 - TypeScript
정적 타입 검사로 코드 품질을 높이고, 런타임 오류를 사전에 방지 - React-query
서버 상태 관리 라이브러리로, API 데이터를 캐싱하고, 데이터 동기화를 효율적으로 처리. - zustand
전역 상태 관리를 쉽게 구현 가능하며, Redux보다 가볍고 사용이 간단. - scss
CSS보다 강력한 기능(중첩, 변수, 믹스인 등)을 제공하여 스타일링을 효율적으로 관리 - axios
API 요청과 에러 처리를 간단하게 처리, API 호출 시 간결하고 직관적인 코드 작성이 가능
- Next.js
- App
- EXPO
EAS를 사용한 빌드, 배포 업데이트를 쉽게 관리, 크로스플랫폼 개발을 빠르게 시작 가능하며, Expo SDK를 활용해 네이티브 기능도 쉽게 구현 가능. 그렇지만 제한된 네이티브 코드로 고생좀 함, 특히 소셜 로그인 구현 부분, - TypeScript, React-query, Zustand
- EXPO
- Web
- 백엔드 node.js, AWS EC2 + S3, MySQL, Swagger, Docker, Redis
✅ 현재 진행 상황
- 완료율 90% 정도
- 네이티브에서의 소셜로그인, 및 스택관리, UI 구현 마무리
- 진행 중
- 아이디 및 비밀번호 찾기
- testflight를 사용하기 위해 빌드 및 제출, 테스트 앱 심사중,
- 해결해야 할 문제 및 추가 기능
- 공지사항에 이미지 추가하기,
- 빌드 및 배포 자동화
✅ 목표
- 사용자 유치
- CI/CD, 개발부터 배포까지의 자동화
✅ 참고 자료
- EXPO : https://docs.expo.dev/
- Kakao Login : https://www.npmjs.com/package/@react-native-seoul/kakao-login
- expo - av : https://docs.expo.dev/versions/latest/sdk/video-av/
- Apple Login : https://docs.expo.dev/versions/latest/sdk/apple-authentication/
- react-query : https://tanstack.com/query/v5/docs/framework/react/overview
1. 개발 배경
지난 8월, 백엔드 친구와 함께 프로젝트를 계획하고 시작했다. 당시에는 둘 다 경험이 부족했기에 일단 해보자는 마음으로 무작정 시작.
먼저 기획 단계에서 주제를 정했다. 요즘 클라이밍이 인기를 끌고 있고, 취미랑 연관된 프로젝트를 하면 재밌을 것 같다는 생각 때문에 클라이밍 관련 플랫폼을 개발하기로 정했다. 이후 각자 프론트엔드와 백엔드에서 사용할 기술 스택을 선정.
프론트엔드는 내가 맡았고, Next.js, TypeScript, SCSS, React-query를 기본 베이스로 선택했다. 이전 프로젝트에서 사용한 적이 있는 기술들이고, 많이 사용해야 익숙해질 것 같았기 때문이다. 전역 상태관리는 Redux Toolkit 대신 Zustand를 도입해 보다 간결하게 구현하기로 했다.
처음에는 PWA를 활용해 앱처럼 보이는 웹을 만들려 했습니다. 하지만 웹앱의 기능적 한계를 느꼈고, 더 네이티브스러운 경험을 제공하기 위해 하이브리드 앱으로의 전환을 생각하게 되었다. 이미 만들어진 웹 코드를 기반으로 Expo를 사용해 앱을 구현하기로 결정!!.
React Native와 Expo는 처음이라 어느정도 익히는데 시간이 좀 걸렸다. 페이지 스택 관리, 폴더 구조, 라우팅 방식 등을 익히는 데 일주일 정도 소요되었던 것 같고, Expo 프로젝트를 반복적으로 생성하고 삭제하면서 감을 잡게 되었다. 결과적으로 약간은 어색하지만 그래도 동작하는 앱을 만들 수 있었다.
2. 기능 관련 및 문제있던 것들
2-1. 로그인
일반 로그인과 소셜 로그인(Apple, Kakao)을 구현했고 서버에서 세션 기반으로 로그인 상태를 관리하여 보안성을 강화했다.
웹에서는 단순히 리다이렉트 시킨 페이지에서 퀴리스트링 값을 서버로 넘겨주면 되었지만 앱은 좀 달랐다.
애플과 카카오에서 등록한 번들id와 라이브러리를 사용해 구현했으며 develop build를 사용하지 않은 기본적인 expo는 네이티브 코드를 사용할 수 없었으므로 로그인 기능이 도대체 왜 안되는지 한참 갈피를 못잡았었다.
expo가 개발 및 빌드에 대해서 굉장히 편리했지만 이런면에선 또 불편하다는 것을 생각했다. 이미 빌드를 한 시점에서 네이티브 기능을 또 작성하게 되면 한번 더 빌드를 해야 기능이 동작되는 것? 사실 이거 빼면 대체적으로 좋긴 했지만
모든게 장점만이 있는 것이 아니었다.
2-2. 동영상 업로드
이 프로젝트의 핵심은 동영상 업로드와 최적화였다. 아무래도 다른 사람의 영상을 보고 비슷한 방법을 공유하는 플랫폼이다보니 신경을 많이 써야했다.
초기방식은 서버가 업로드 요청을 받아 파일을 S3에 저장하고, 저장된 파일의 URL을 클라이언트에 반환하는 방식.
하지만, 동영상을 단순히 선택만 했을 뿐인데도 S3에 업로드가 되는 비효율적인 방식이라 조금 바꾸기로 결정!
- 동영상을 선택하면 **로컬 URL(file://)**을 상태에 저장하고 미리보기로 보여주기
- 최종적으로 게시물 업로드 시, 로컬 URL과 다른 데이터를 FormData로 묶어 서버에 전송
- 서버는 해당 데이터를 받아 S3에 파일을 업로드한 뒤, S3 URL을 반환
- 반환된 S3 URL과 게시물 데이터를 묶어 최종 업로드를 완료
이 방식은 불필요한 서버 트래픽을 줄이고, 최종적으로 제출된 데이터만 서버에 반영하므로 더 효율적인 방식이었다.
또한 프로그레스바도 넣고 싶었다. 가장 이상적인 방식은 인스타그램처럼 비동기로 업로드하며 프로그레스 바를 표시하고, 다른 페이지로 이동할 수 있도록 하고 싶었지만 웹에선 어느정도 가능, 하지만 Expo 환경에서 Axios의 업로드 프로그레스 바를 구현하기 어려웠고, 일단 앱 배포 먼저 하자는 생각에 모달을 보여줘 페이지를 이동시키지 않고 업로드를 기다리는 방식으로 대체했다.
2-3. 캐시 관리
React-query는 데이터 동기화와 캐싱에 강점이 있지만, 너무 막 쓴 탓에 로그아웃 구현 중 예상치 못한 문제가 발생했다.
- A 계정으로 로그인 → 프로필 페이지 → 설정 페이지에서 로그아웃 → 홈으로 이동.
- B 계정으로 로그인 → 설정 페이지에 진입하자마자 자동으로 로그아웃 발생.
이것저것 콘솔 찍고 테스트 해본 결과 원인은
로그아웃 API 요청을 useQuery로 관리하면서, 로그아웃 쿼리의 성공 상태가 캐시에 남아 있었기 때문인 듯 싶다.
동일한 쿼리 키로 인해 설정 페이지에 진입하자마자 이전 쿼리가 재실행되며 로그아웃이 발생.
따라서 쿼리를 그대로 사용할거면 queryClient.reamoveQuery를 사용하면 해결이 되었지만 굳이 로그아웃을 쿼리로 관리 할 이유가 없어서 React-query에서 제거하고, 단순히 API 호출 후 상태를 갱신하는 방식으로 변경해 캐시 관리를 더 단순화하고 예상치 못한 동작을 방지했다.
react-query와 관련된 또다른 문제
3. 전역 상태 관리
Zustand를 도입해 전역 상태 관리를 구현했다. zustand는 너무 편했따. 물론 찍어먹는 수준으로 사용했기 때문에 그럴 수도,, 일단 초기 설정이 간단하고, 필요에 따라 Store를 정의해 바로 사용할 수 있다는 점이 큰 장점이 있었다.
내 프로젝트에서는 사용자 ID와 클라이밍장 이름 같은 데이터를 전역 상태로 관리했고
Redux에 비해 설정이 적고 간결하게 동작했기에 프로젝트 규모와 요구사항에 적합하다고 느꼈다.
만들다보니 욕심이 막 생긴다. 사용하는 유저가 있으면 좋겠고,... 나름 어느정도 인지도가 오르면 좋겠다는 그냥 막연한 희망.... 그냥 웹사이트를 만드는 것보다 요즘 앱을 많이 사용하니 실제 스토어에 배포할 수 있는 것을 만든다는 생각에 재밌게 진행했다. 물론 앱 관련해서 아무것도 몰랐기 때문에 삽질도 그만큼 많이 하고..
일단은 배포가 스토어 승인이 목적이고 그 후에 기능 개발과 개선해야될 부분을 정해서 꾸준하게 디벨롭하고 싶다는 생각을 가지게 되었다.
'프로젝트 답지' 카테고리의 다른 글
앱스토어 승인 리젝 사유 모음집 => 승인 통과된 결과 (1) | 2024.12.13 |
---|---|
react-query의 데이터 깜빡임 해결 건(placeholderData) (0) | 2024.12.09 |
[Dap JI ] react-native-seoul/kakao-login사용해서 카카오 로그인 (0) | 2024.12.03 |
[Dap JI ] expo expo-apple-authentication 사용해서 애플 로그인 (3) | 2024.12.01 |
[Dap JI ] 갑자기 되던 모달이 안나오는 이유 발생 (1) | 2024.11.27 |