- version :
1.0.2
- 배포일 :
2024-04-23
- 강원대버스(KNUBus) ver 1
Android
우선 배포.- 순환버스 운행 기간인
2024-033-04
부터2024-06-24
에 따름.
- 대상 사용자 : 강원대학교 학생 및 교직원.
- 프로젝트 목적 : 순환버스 운행 정보의 접근성과 가시성 향상.
- 실시간 순환버스 회차 정보 제공
- 전체 순환버스 노선도 확인
- 전체 순환버스 시간표 확인
- 강원대 종강일 디데이 확인
- 강원대 학사일정 확인
- Expo를 사용하여 개발되었으며, Expo를 통해 배포합니다.
- Google Cloud Platform의 API를 활용합니다.
- 안드로이드 앱은 Google Play 콘솔을 통해 업로드합니다.
- 구희원: UI 디자인 및
Header.js
,MapScreen.js
모달 구현. HeHelee GitHub - 최수영:
TimeScreen.js
구현. scove03 GitHub - 허윤수:
App.js
,Navigation.js
,HomeScreen.js
구현 및MapScreen.js
지도 구현, 애플리케이션 전체 리팩토링 sugoring GitHub
- 에디터(IDE) : VS Code
- 서버 및 패키지 관리 : Node.js(v20.11.1 LTS), npm(v10.5.0)
- 프로젝트 관리 : Expo
- 버전 관리 : Git, Github
- 문서 관리 : Notion
- 메인 색상 :
#38B6FF
- 반전 색상 :
#FF5757
- 버튼 색상 #1 :
#4A90E2
- 버튼 색상 #2 :
#50E3C2
- 글자 색상 :
#2c3e50
- 배경 색상 :
#F5F5F5
- 회색 색상 :
#B0BEC5
📦src
┣ 📂components
┃ ┣ 📜Header.js
┃ ┣ 📜Round.js
┃ ┗ 📜Timeline.js
┣ 📂data
┃ ┣ 📜apiKey.js
┃ ┣ 📜operation.json
┃ ┗ 📜schedule.json
┣ 📂pages
┃ ┣ 📜HomeScreen.js
┃ ┣ 📜MapScreen.js
┃ ┗ 📜TimeScreen.js
┗ 📜Navigation.js
- View (container) : 앱의 전체 컨테이너입니다.
- StatusBar : 앱의 상태 표시줄을 설정하며, 텍스트 스타일을 'dark-content'로 지정해 어두운 색상의 텍스트를 표시합니다.
- SafeAreaView : iOS 기기에서 노치나 홈 버튼으로 인해 내용이 가려지지 않도록 안전 영역을 설정합니다.
- Header : 앱의 상단에 위치하며,
Header
컴포넌트를 표시합니다. - Navigation : 화면 간 이동을 가능하게 하는 하단 탭
Navigation
컴포넌트를 표시합니다.
- NavigationContainer : 네비게이션의 전체 컨테이너입니다.
- Tab.Navigator : 하단 탭 기반의 네비게이션 구조를 제공하고, 각 탭의 설정을 정의합니다.
- Tab.Screen (Home) : "Home" 화면으로의 탭을 설정하고, 해당 컴포넌트(
HomeScreen
)를 연결합니다. - Tab.Screen (운행노선도) : "운행노선도" 화면으로의 탭을 설정하고, 해당 컴포넌트(
MapScreen
)를 연결합니다. - Tab.Screen (운행시간표) : "운행시간표" 화면으로의 탭을 설정하고, 해당 컴포넌트(
TimeScreen
)를 연결합니다. - Icon : 각 탭에서 사용될 아이콘을 생성하고, 탭이 활성화되었는지에 따라 아이콘 스타일을 변경합니다.
- View (container) : 헤더의 전체 컨테이너로, 로고가 중앙에 위치합니다.
- Pressable : 로고 이미지를 포함하며, 클릭 시 지정된 웹 페이지로 연결합니다.
- Image : KNUBus 앱의 로고를 표시합니다.
- Linking : 사용자가 로고를 클릭할 때 외부 링크로 연결합니다.
- View (container) : 전체 컨테이너로, 모든 하위 컴포넌트를 중앙에 배치합니다.
- Text (dateText) : 선택한 날짜를 사용자에게 표시합니다.
- Text (dateNameText) : 공휴일 또는 기념일의 이름을 표시합니다.
- Pressable : 날짜 변경 버튼(이전 날짜, 다음 날짜, 오늘 날짜로)을 제공합니다.
- Animated.View (buttonTo) : 버튼(오늘 날짜로)을 깜빡이는 애니메이션과 함께 제공합니다.
- View (buttonContainer) : 날짜 변경 버튼들을 수평으로 배열하여 제공합니다.
- View (roundContainer) : 버스 운행 상태를 표시하는
Round
컴포넌트를 표시합니다. - useState : 상태(선택한 날짜, 휴일 정보 등)를 관리합니다.
- useEffect : 사이드 이펙트(날짜 변경, 휴일 정보 요청, 애니메이션 실행 등)를 처리합니다.
- Vibration : 버튼을 누를 때 진동을 제공합니다.
- View (container) : 전체 컨테이너로, 모든 하위 컴포넌트를 중앙에 배치합니다.
- Text (timeText) : 현재 시간을 표시합니다.
- Text (roundText) : 선택한 회차의 정보를 표시합니다.
- Pressable : 회차 변경 버튼(이전 회차, 다음 회차, 현재 회차로)을 제공합니다.
- Animated.View (buttonTo) : 버튼(현재 회차로)을 깜빡이는 애니메이션과 함께 제공합니다.
- Image : 비운행 날짜에는 Mascot 이미지를 표시합니다.
- View (stateListContainer) : 상태(운행 종료, 현재 운행, 운행 예정)를 표시합니다.
- View (infoContainer) : 운행과 관련된 추가 정보나 주의사항을 표시합니다.
- Timeline :
Timeline
컴포넌트를 표시합니다. - useState, useEffect : 상태(현재 시간, 인덱스 등)를 관리하고, 업데이트합니다.
- Vibration : 버튼을 누를 때 진동을 제공합니다.
- ScrollView : 상하 스크롤을 제공합니다.
- View (container) : 전체 컨테이너로, 모든 하위 컴포넌트를 수직 배치합니다.
- View (timelineContainer) : 전체 정보를 표시합니다.
- View (timeline) : 개별 정보를 표시합니다.
- Animated.View (circle) : 상태(현재, 과거, 미래)을 애니메이션과 함께 제공합니다.
- View (stopInfo) : 개별 정류장 정보(시간, 이름)을 표시합니다.
- parseTime 함수 : 문자열로 된 시간을 시간과 분으로 분리하여 객체로 반환합니다.
- isPast 함수 : 주어진 시간이 현재 시간보다 과거인지 확인합니다.
- isCurrent 함수 : 주어진 시간이 현재 시간인지 확인합니다.
- useState, useEffect : 상태(애니메이션 등)를 관리하고, 업데이트합니다.
- View (container) : 운행 노선도의 전체 컨테이너입니다.
- MapView : 지도를 표시하고, 초기 지역 설정을 포함합니다.
- Marker : 각 위치에 대한 Marker를 표시합니다.
- Polyline : 지정된 경로를 지도 위에 표시합니다.
- ScrollView : 좌우 스크롤을 제공합니다.
- Modal : 선택된 위치에 대한 정보를 보여주는 팝업 창을 표시합니다.
- View (bottomContainer) : 화면 하단에 설명 텍스트를 표시합니다.
- View (container) : 운행 시간표의 전체 컨테이너입니다.
- ScrollView : 좌우 스크롤을 제공합니다.
- Table : 'react-native-table-component'에서 제공하는
Table
컴포넌트를 사용합니다. - Row (RenderHead) : 테이블의 Head를 구성하는 컴포넌트로, 각 열의 제목을 표시합니다.
- Row (RenderRows) : 테이블의 Rows를 구성하는 컴포넌트로, 각 행을 동적으로 생성하여 표시합니다.
- React-Native: 웹 개발 경험을 바탕으로 React Native로 모바일 개발을 시작하였습니다. 웹에서 사용하던 기본적인 컴포넌트 기반 구조가 유사해 접근이 쉬웠지만, 다양한 모바일 기기의 스크린 크기 차이로 결과물의 일관성 유지에 어려움이 있었습니다. (웹의 CSS와 달리) 모든 컴포넌트에 스타일을 개별적으로 지정하여야 했고, 이로 인해 코드의 가독성도 떨어졌습니다. 글로벌 스타일을 설정할 수 없다는 문제도 있었습니다. 이를 극복하기 위해, 레이아웃과 스타일에 관한 명확한 가이드라인을 정립하여 여러 컴포넌트에서 일관된 사용자 경험을 제공할 수 있도록 개선하였습니다.
- React-Native 라이브러리: React Native를 사용하며, 많은 기능이 라이브러리 형태로 제공되는 것에 놀랐습니다. 예를 들어, React에서는 div 태그를 사용해 다양한 요소를 만들지만, React Native에서는 필요한 버튼을 구현할 때 이미 만들어진 Button, Touchable, Pressable과 같은 컴포넌트를 사용해야 합니다. 또한, div와 유사한 기능을 하는 View 컴포넌트 내에 텍스트를 넣기 위해서는 Text 컴포넌트가 필수입니다. 이러한 점은 편리할 수 있지만, 처음에는 컴포넌트의 종류를 잘 모르기 때문에 적절한 컴포넌트를 찾아 사용하는 것이 어색하고 번거로웠습니다. 하지만, 각 요소의 용도가 명확하여 div로 가득 찬 코드보다 가독성이 더 좋다는 장점이 있습니다. 또한, 지도 구현을 복잡하게 예상했으나, 라이브러리를 통해 쉽게 해결할 수 있었고, 다음 업데이트에서는 사용자의 위치도 표시할 수 있도록 개선할 예정입니다.
- 기획부터 배포까지: 필요한 서비스로 판단하고 바로 개발에 착수했습니다. 🏃♂️ 시간이 촉박하여 애플리케이션이 효율적인 구조를 갖추었는지는 확신하기 어렵습니다... 🤔 다음 업데이트에서는 컴포넌트 분리를 통해 재사용성을 높이고, 백엔드를 구축하여 API를 통해 데이터를 관리하려고 합니다. 이번에 공공데이터 API를 활용한 것은 전체 개발 프로세스를 빠르게 파악하는 데 큰 도움이 되었습니다! 🎉 배포를 위해 앱을 번들링하는 과정에서 어려움을 겪었습니다. 이를 간편하게 해결하기 위해 Expo라는 툴을 사용했는데, Expo는 사용하지 않는 모듈까지 번들링되어 앱의 용량이 커지는 단점이 있지만, 간단한 앱 배포용으로는 학습하기에 좋은 선택이었습니다. Google API 활용 중 빌드 연결 문제가 발생했으나, 개발자 커뮤니티를 통해 도움을 받고 HTTP 관련 설정 문제임을 이해할 수 있었습니다.
- 팀워크 : 프론트엔드 팀원과 함께 프로젝트를 진행하는 것은 처음이었습니다. 팀원들이 적극적으로 아이디어를 내주고 잘 따라와 준 덕분에 모두 만족할 수 있는 결과를 얻었습니다. 고맙습니다! 🙌 각 페이지와 컴포넌트를 분리하여 작업한 방식이 우리 팀에 잘 맞았고, 기능 구현 후 코드 리뷰 시간을 통해 서로 성장할 수 있는 소중한 시간이었습니다. 📈
- 첫 프론트앤드 작업물 : 올해 처음 프론트앤드에 관심을 갖게 되었고, React Native로 Header와 MapScreen을 일부 맡아서 작업했습니다. 처음이어서 Chat-gpt를 많이 이용했지만 더 열심히 배워서 Chat-gpt의 의존도를 낮춰야 겠다고 생각했습니다.
- 효율적인 로직 작성하기 : MapScreen을 만들때 로직이 엄청 길었으나 동작은 잘 되었습니다. 하지만 좀 더 효율적으로 코딩을 하고 싶다는 생각이 들었습니다. 그래서 반복되는 부분을 함수로 묶어서 간략하게 로직을 구현했습니다. 이런 경험을 통해서 코드를 좀 더 효율적으로 설계하는 능력을 키워야 겠다고 생각했습니다.
- 반응형 디자인 사용하기 : 지도에 있는 정류장을 눌렀을 때 팝업이 뜨도록 하고 싶었으나, 제가 설계했던 부분이 반응형이 아니어서 핸드폰의 기종마다 크기가 달라진다는 점이 아쉬웠습니다. 그래서 그 부분은 @허윤수 언니가 맡아서 해줬습니다. 이런 경험을 통해서 반응형으로 어플을 제작하는 것이 중요하다는 것을 깨달았습니다.
- 깃허브 사용법 : 깃허브를 이용해서 파일을 형상관리하는 법을 잘 몰랐었는데, 이번 기회를 통해서 제대로 익힐 수 있었습니다. 저는 GUI툴인 소스트리를 이용했고, Repository에서 Clone을 해서 Pull을 해와서 내용을 받고, 제가 수정하면 Commit하고 Push하는 방식으로 이뤄진다는 동작원리를 알게 되었습니다. 특히 Repository에서 branch를 이용하는 이유와 방식에 알게 되었습니다. branch를 사용하는 이유는 한 branch에다가 몽땅 기능들을 다 만들어버리면, merge하기전에 기능들이 다 섞이기 때문입니다. 그래서 기능이 섞이고 파일이 복잡해지는 것을 방지하기 위함이라고 저는 생각합니다.
- 팀워크 : 프론트앤드를 처음 입문하는 데 어려움이 있었음에도, 잘 도와주고 해서 좋은 결과물을 얻을 수 있었습니다. 깃허브를 이용하는 방법도 많이 서툴렀었는데, 이번 기회를 통해서 깃허브를 이용해서 팀워크를 하는 방법을 제대로 익힐 수 있는 시간이어서 좋았습니다. 😊
- 첫 프로그램 개발을 진행하면서 git 및 React Native 배우고 사용해 보았습니다. 초기 세팅 및 기본 개념공부만 해도 복잡하고 시간이 걸리며 여러 오류 등이 발생하였지만 팀원들과 같이 여러 문제점을 소통하며 해결해 나가면서 React Native에 전반적인 부분을 익혔고 개발 부분에서 많은걸 배울 수 있었습니다.