한세대학교 학생들을 위한 택시 동승 매칭 및 실시간 셔틀버스 정보 플랫폼
"Simple, Secure, Resilient" - 단순한 구조, 강력한 보안, 견고한 사용자 경험
💡 개발 환경 설정 없이 앱을 테스트하고 싶은 분들(백엔드, 디자이너 등)을 위한 빌드입니다.
| 플랫폼 | 설치 링크 | 최종 업데이트 |
|---|---|---|
| Android | 빌드 페이지 | 2026-01-01 |
| iOS | 빌드 페이지 | 2026-01-01 |
Android (APK):
- 위 링크 접속 → "Install" 클릭
- QR 코드 스캔 또는 APK 다운로드
- "알 수 없는 앱 설치" 허용 후 설치
iOS (시뮬레이터 전용):
⚠️ 요구 사항: macOS + Xcode 설치 필요 (Windows에서는 불가)
- 위 링크 접속 →
.tar.gz파일 다운로드 - 다운로드한 파일 압축 해제 →
.app폴더 생성 - Xcode의 iOS 시뮬레이터 실행 (Xcode → Open Developer Tool → Simulator)
.app폴더를 시뮬레이터 화면에 드래그 앤 드롭하여 설치- 시뮬레이터 홈 화면에서 앱 실행
💡 팁: 시뮬레이터에서
Cmd + Shift + H로 홈 화면 이동
앱을 처음 실행하면 업데이트 서버 URL을 입력하는 화면이 나타납니다. 아래 URL을 입력해주세요:
https://u.expo.dev/1345ccf1-9ecc-47e3-b6f2-1cd13408a487?channel-name=development
💡 팁: 한 번 입력하면 이후에는 자동으로 최신 버전을 받아옵니다.
⚠️ 참고: 새 빌드 생성 시 링크가 변경됩니다. 업데이트된 빌드는 이 표를 확인해주세요.
💡 Orval이란? 백엔드 API 명세서(OpenAPI)를 기반으로 TypeScript 타입, API 호출 함수, React Query 훅을 자동으로 생성해주는 도구입니다.
| 장점 ✅ | 설명 |
|---|---|
| 타입 자동 생성 | 타입 수동 작성 불필요 |
| 백엔드 동기화 | API 변경 시 타입 오류로 바로 감지 |
| 생산성 향상 | 반복적인 코드 작성 제거 |
# 백엔드 API 명세서 URL을 orval.config.ts에 설정한 후
yarn api:generate// 생성된 훅을 바로 사용
import { useGetMatchList } from '@/api/generated';
const { data, isLoading } = useGetMatchList();
⚠️ 주의:src/api/generated/폴더는 직접 수정 금지! 코드 생성 시 덮어씌워집니다.
👉 자세한 사용법: src/api/generated/README.md
- Node.js: v18 이상 (다운로드)
- Yarn: 패키지 매니저 (
npm install -g yarn)
⚠️ 네이티브 빌드 필수 요구 사항 (Android/iOS 실제 기기 또는 에뮬레이터 테스트 시)이 프로젝트는 네이티브 모듈을 사용하므로 Expo Go와 호환되지 않습니다. 실제 디바이스나 에뮬레이터에서 테스트하려면 아래 환경 설정이 필요합니다:
- Java Development Kit (JDK): 17 버전 (권장) 또는 11 버전
- Android Studio: Android 빌드용 (macOS/Windows)
- Xcode: iOS 빌드용 (macOS만 가능)
# 프로젝트 폴더로 이동
cd hansei-ro
# 필요한 패키지 설치
yarn install프로젝트 루트에 .env.local 파일을 생성하고 다음 내용을 입력하세요:
EXPO_PUBLIC_API_URL=http://localhost:3000💡 팁: 백엔드 서버 주소를 팀원에게 확인하세요!
# Expo 개발 서버 실행
yarn start
⚠️ 중요: 이 프로젝트는 네이티브 모듈을 사용하므로 Expo Go와 호환되지 않습니다. 아래 환경 설정을 완료한 후npx expo run:android또는npx expo run:ios명령어를 사용해야 합니다.
중요: React Native는 JDK 17 버전을 권장합니다.
- ✅ JDK 17 (권장) - 안정적이고 최신 기능 지원
- ✅ JDK 11 (지원) - 작동하지만 17 권장
- ❌ JDK 8 - 너무 오래되어 호환성 문제 발생 가능
⚠️ JDK 21+ - 일부 Gradle 플러그인과 호환성 문제 가능
# macOS/Linux/Windows 공통
java -version출력 예시:
openjdk version "17.0.9" 2023-10-17 LTS
OpenJDK Runtime Environment Zulu17.46+19-CA (build 17.0.9+8-LTS)
💡 Zulu JDK 17을 권장하는 이유:
- 무료 오픈소스 (상업적 사용 가능)
- 장기 지원(LTS) 버전
- React Native 공식 문서 권장
- macOS/Windows 모두 지원
💡 권장: 개발 단계에서는 iOS 시뮬레이터 사용을 권장합니다.
실제 iPhone은 개발자 계정 등록, 인증서 설정 등 추가 작업이 필요하므로,
최종 테스트 단계에서만 사용하는 것이 효율적입니다.
-
App Store에서 Xcode 다운로드 및 설치
-
터미널에서 Command Line Tools 설정:
sudo xcode-select --install
sudo gem install cocoapodsnpx expo run:ios- 자동으로 iOS 시뮬레이터가 실행됩니다
- 별도의 개발자 계정이나 인증서 설정 없이 바로 테스트 가능합니다
- 특정 디바이스 선택:
npx expo run:ios --simulator="iPhone 15 Pro"
- iPhone을 USB로 연결
- Xcode에서 개발자 계정 등록 필요
npx expo run:ios --device- Android Studio 다운로드 및 설치
- Android Studio 실행 → More Actions → SDK Manager
- SDK Platforms: Android 13.0 (API 33) 이상 설치
- SDK Tools: Android SDK Build-Tools, Android Emulator 설치
~/.zshrc 또는 ~/.bash_profile에 추가:
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools저장 후 터미널 재실행 또는:
source ~/.zshrc방법 1: Homebrew 사용 (권장)
# Zulu JDK 17 설치
brew install --cask zulu@17방법 2: 직접 다운로드
- Zulu JDK 17 다운로드
.dmg파일 다운로드 후 설치
설치 확인
java -version
# "openjdk version 17.x.x"가 출력되어야 함여러 Java 버전이 설치된 경우
# Java 17로 기본 버전 설정
export JAVA_HOME=$(/usr/libexec/java_home -v 17)
# ~/.zshrc에 추가하면 영구 적용
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 17)' >> ~/.zshrc
source ~/.zshrc- Android Studio에서 AVD(가상 디바이스) 생성
- 터미널에서 실행:
npx expo run:android- 개발자 옵션 활성화 (설정 → 휴대전화 정보 → 빌드 번호 7회 탭)
- USB 디버깅 활성화
- USB로 연결 후:
npx expo run:android --device
⚠️ iOS 빌드는 Windows에서 불가능합니다. macOS 또는 Expo EAS Build 서비스를 사용하세요.
- Android Studio 다운로드 및 설치
- Android Studio 실행 → More Actions → SDK Manager
- SDK Platforms: Android 13.0 (API 33) 이상 설치
- SDK Tools: Android SDK Build-Tools, Android Emulator 설치
-
제어판 → 시스템 → 고급 시스템 설정 → 환경 변수
-
시스템 변수에 새로 만들기:
변수 이름: ANDROID_HOME 변수 값: C:\Users\[사용자명]\AppData\Local\Android\Sdk -
Path 변수에 추가:
%ANDROID_HOME%\platform-tools %ANDROID_HOME%\emulator
다운로드 및 설치
- Zulu JDK 17 (Windows x64) 다운로드
.msi인스톨러 실행- ✅ 중요: 설치 중 "Add to PATH" 옵션 반드시 체크!
설치 확인 (PowerShell 또는 CMD)
java -version
# "openjdk version 17.x.x"가 출력되어야 함JAVA_HOME 환경 변수 설정 (자동 설정 안 된 경우)
-
제어판 → 시스템 → 고급 시스템 설정 → 환경 변수
-
시스템 변수에서 "새로 만들기":
변수 이름: JAVA_HOME 변수 값: C:\Program Files\Zulu\zulu-17 -
Path 변수에 추가:
%JAVA_HOME%\bin -
PowerShell 재시작 후
java -version재확인
여러 Java 버전이 설치된 경우
- JAVA_HOME을 JDK 17 경로로 설정
- Path에서 JDK 17의 bin 경로가 다른 Java 경로보다 위에 있는지 확인
- Android Studio에서 AVD(가상 디바이스) 생성
- PowerShell 또는 CMD에서 실행:
npx expo run:android- 개발자 옵션 활성화 (설정 → 휴대전화 정보 → 빌드 번호 7회 탭)
- USB 디버깅 활성화
- USB로 연결 후:
npx expo run:android --device# 현재 사용 중인 Java 버전 확인
java -version
# macOS: JAVA_HOME 확인
echo $JAVA_HOME
# Windows: JAVA_HOME 확인
echo %JAVA_HOME%- JDK 17이 제대로 설치되었는지 확인
- JAVA_HOME 환경 변수가 올바르게 설정되었는지 확인
- 터미널/PowerShell 재시작 후 재시도
# 설치된 모든 Java 버전 확인
/usr/libexec/java_home -V
# Java 17 사용
export JAVA_HOME=$(/usr/libexec/java_home -v 17)cd ios
pod install
cd ..
npx expo run:ioscd android
./gradlew clean
cd ..
npx expo run:android- 터미널/PowerShell을 완전히 종료 후 재실행
- macOS:
echo $ANDROID_HOME으로 확인 - Windows:
echo %ANDROID_HOME%으로 확인
이 프로젝트는 Feature-Based Architecture (기능 중심 아키텍처)를 사용합니다.
"택시 매칭 기능을 수정하고 싶다" → src/features/match/ 폴더만 보면 됩니다!
hansei-ro/
├── app/ # 📱 화면 라우팅 (Expo Router)
│ ├── (tabs)/ # 하단 탭 네비게이션 (홈, 버스, 매칭, 채팅, 프로필)
│ └── _layout.tsx # 전역 설정 (Provider 등록)
│
├── src/
│ ├── features/ # 🎯 기능별 폴더 (핵심!)
│ │ ├── _template/ # 📋 새 기능 추가 시 복사할 템플릿
│ │ ├── auth/ # 로그인, 회원가입
│ │ ├── match/ # 택시 매칭
│ │ ├── chat/ # 실시간 채팅
│ │ └── bus/ # 버스 정보
│ │
│ ├── shared/ # 🔧 공통 유틸리티
│ │ ├── ui/ # 재사용 가능한 UI (Button, Card 등)
│ │ └── lib/ # 기능 함수 (axios, storage 등)
│ │
│ └── store/ # 🌍 전역 상태 (테마, 인증)
│
└── assets/ # 🎨 이미지, 폰트 파일
| 폴더 | 설명 | 예시 |
|---|---|---|
app/ |
화면 라우팅 (로직 없음, 렌더링만!) | home.tsx, match.tsx |
src/features/ |
기능별 비즈니스 로직 + UI | match/api.ts, MatchCard.tsx |
src/shared/ui/ |
여러 곳에서 재사용하는 컴포넌트 | Button.tsx, Skeleton.tsx |
src/shared/lib/ |
공통 유틸리티 (날짜 포맷, API 클라이언트 등) | axios.ts, formatters.ts |
새로운 기능(예: 알림)을 만들 때는 _template 폴더를 복사하세요.
# Windows (PowerShell)
Copy-Item -Recurse src\features\_template src\features\notification
# macOS/Linux
cp -r src/features/_template src/features/notification복사한 notification/ 폴더 안을 보면:
notification/
├── api/ # 서버와 통신 (백엔드 API 호출)
├── hooks/ # React Query 훅 (서버 데이터 가져오기)
├── store/ # Zustand 스토어 (클라이언트 상태 관리)
├── ui/ # 이 기능 전용 컴포넌트
└── types/ # TypeScript 타입 정의
💡 "언제 폴더를 만들고, 언제 파일로 두나요?"
- 파일이 1~2개: 폴더 대신
api.ts같은 단일 파일로 시작- 파일이 3개 이상:
api/폴더를 만들어 분리👉 작게 시작하고, 커지면 확장하세요!
// src/features/notification/types/notification.ts
export interface Notification {
id: string;
title: string;
message: string;
createdAt: string;
}// src/features/notification/api.ts
import axios from '@/shared/lib/axios';
import { Notification } from './types/notification';
export async function getNotifications(): Promise<Notification[]> {
const response = await axios.get('/api/notifications');
return response.data;
}// src/features/notification/hooks/useNotificationsQuery.ts
import { useQuery } from '@tanstack/react-query';
import { getNotifications } from '../api';
export function useNotificationsQuery() {
return useQuery({
queryKey: ['notifications'],
queryFn: getNotifications,
});
}// src/features/notification/ui/NotificationCard.tsx
import { View, Text } from 'react-native';
interface NotificationCardProps {
title: string;
message: string;
}
export function NotificationCard({ title, message }: NotificationCardProps) {
return (
<View>
<Text>{title}</Text>
<Text>{message}</Text>
</View>
);
}// app/(tabs)/notifications.tsx
import { FlatList } from 'react-native';
import { useNotificationsQuery } from '@/features/notification/hooks/useNotificationsQuery';
import { NotificationCard } from '@/features/notification/ui/NotificationCard';
export default function NotificationsScreen() {
const { data, isLoading } = useNotificationsQuery();
if (isLoading) return <Text>로딩 중...</Text>;
return (
<FlatList
data={data}
renderItem={({ item }) => <NotificationCard title={item.title} message={item.message} />}
/>
);
}| 상황 | 위치 | 예시 |
|---|---|---|
| 1개 기능에서만 사용 | features/[기능]/ui/ |
MatchCard.tsx → features/match/ui/ |
| 2~3곳에서 사용 (아직 확실하지 않음) | 그냥 원래 위치에 둠 | 아직 features/match/ui/에 둠 |
| 3곳 이상에서 사용 (확실히 공통화 필요) | shared/ui/ |
Button.tsx → shared/ui/ |
💡 원칙: "3번째 사용할 때" 공통 폴더로 이동하세요. (너무 이른 추상화 방지)
💡 자세한 개발 컨벤션은 CONVENTIONS.md를 참고하세요! Git 사용법, 브랜치 전략, 커밋 규칙, TypeScript 타입 작성 규칙, 코드 스타일 등 모든 개발 규칙이 정리되어 있습니다.
형식: <타입>(<범위>): <제목>
타입:
feat- 새로운 기능 추가 (UI/디자인 포함)fix- 버그 수정refactor- 코드 개선 (기능 변경 없음)docs- 문서 수정chore- 빌드/설정 작업 (Prettier 등)
범위 (선택사항):
auth- 인증 관련match- 매칭 관련chat- 채팅 관련bus- 버스 관련
예시:
git commit -m "feat(auth): 로그인 페이지 UI 구현"
git commit -m "feat(ui): 로그인 버튼 색상 변경"
git commit -m "fix(match): 매칭 시간 계산 오류 수정"💡 자세한 커밋 규칙은 CONVENTIONS.md를 참고하세요!
PR을 올릴 때 다음 체크리스트를 확인하세요:
- 빌드 에러 없음:
yarn start가 정상 실행되나요? - 불필요한 코드 제거:
console.log, 주석 정리했나요? - 폴더 구조 확인:
- 1개 기능에서만 쓰는 컴포넌트를
shared/에 두지 않았나요? - 파일이 1~2개인데 불필요한 폴더를 만들지 않았나요?
- 1개 기능에서만 쓰는 컴포넌트를
- 코드 스타일:
yarn format실행했나요?
A: src/features/[기능명]/api.ts에 작성하세요.
// src/features/match/api.ts
export async function getMatchList() {
const response = await axios.get('/api/matches');
return response.data;
}A: React Query 훅을 사용하세요.
// src/features/match/hooks/useMatchListQuery.ts
import { useQuery } from '@tanstack/react-query';
import { getMatchList } from '../api';
export function useMatchListQuery() {
return useQuery({
queryKey: ['matches'],
queryFn: getMatchList,
});
}화면에서 사용:
const { data, isLoading } = useMatchListQuery();A: Zustand 스토어를 사용하세요.
// src/features/match/store/useMatchStore.ts
import { create } from 'zustand';
interface MatchState {
selectedMatchId: string | null;
setSelectedMatchId: (id: string) => void;
}
export const useMatchStore = create<MatchState>((set) => ({
selectedMatchId: null,
setSelectedMatchId: (id) => set({ selectedMatchId: id }),
}));| 파일 개수 | 권장 방법 | 예시 |
|---|---|---|
| 1~2개 | 단일 파일 (api.ts) |
src/features/bus/api.ts |
| 3개 이상 | 폴더로 분리 | src/features/match/api/ |
src/features/폴더에서 해당 기능 찾기 (예:match/)- 폴더 안에서 수정할 파일 찾기:
- API 수정 →
api.ts또는api/ - UI 수정 →
ui/폴더 - 상태 관리 수정 →
store/폴더
- API 수정 →
- 빌드 에러: 터미널 메시지를 읽고 파일 경로 확인
- API 에러:
src/shared/lib/axios.ts인터셉터 로그 확인 - 린트 에러:
yarn lint실행 후 메시지 확인
- 예제 코드 보기:
src/features/_template/의 README를 읽어보세요 - 실습: 간단한 기능 하나를 만들어보세요 (예: 프로필 화면 수정)
- 질문하기: 막히면 팀원에게 즉시 물어보세요!
문제가 발생하거나 질문이 있으면 팀 채팅방에 언제든지 올려주세요!
Happy Coding! 🚀