-## 🏗️ 프로젝트 구조
+

-```
-TimeSpot/
-├── Projects/
-│ ├── App/ # 메인 애플리케이션
-│ ├── Presentation/ # UI 계층
-│ ├── Domain/ # 🔥 도메인 계층 (비즈니스 로직 + Protocol)
-│ │ ├── Entity/ # 도메인 엔티티 + Entity Protocol
-│ │ ├── UseCase/ # 비즈니스 로직 + UseCase Protocol
-│ │ └── DomainInterface/ # Domain 계층 인터페이스 모듈
-│ ├── Data/ # 데이터 계층 (데이터 접근 + Model)
-│ │ ├── Model/ # 데이터 전송 객체 (DTO, API Response)
-│ │ ├── Repository/ # Repository 구현체 (Domain Protocol 구현)
-│ │ ├── API/ # REST API 클라이언트
-│ │ └── Service/ # 데이터 처리 서비스
-│ ├── Network/ # 네트워크 계층
-│ │ ├── Networks/ # 네트워크 기본 설정 및 클라이언트
-│ │ ├── Foundations/ # 네트워크 기반 유틸리티
-│ │ └── ThirdPartys/ # 네트워크 써드파티 라이브러리 (AsyncMoya, WeaveDI)
-│ └── Shared/ # 공통 모듈
-│ ├── DesignSystem/ # 공통 UI 컴포넌트, 폰트 등
-│ ├── Shared/ # 공통 공유 모듈
-│ └── Utill/ # 공통 유틸리티
-├── Tuist/
-│ ├── Package.swift
-│ └── ProjectDescriptionHelpers/
-└── Plugins/
-```
+**여행의 새로운 시작, 대기 시간을 활용한 스마트한 여정**
+
+
+
+
+
+
+[📱 App Store](#) | [🎯 Features](#-주요-기능) | [🏗 Architecture](#-프로젝트-아키텍처) | [🚀 Quick Start](#-빠른-시작)
-
+---
-## 📦 주요 모듈 설명
+
-- **App**: 메인 애플리케이션 모듈
-- **Presentation**: UI 계층 (ViewController, ViewModel)
-- **Domain**: 도메인 계층 (Entity, UseCase, Interface)
-- **Data**: 데이터 계층 (Model, Repository, API, Service)
-- **Network**: 네트워크 계층 (Networks, Foundations, ThirdPartys)
-- **Shared**: 공통 모듈 (DesignSystem, Shared, Utill)
+## 📖 프로젝트 소개
-## 🚀 빠른 시작
+**TimeSpot**은 KTX 출발 전 대기 시간을 효율적으로 활용할 수 있도록 도와주는 iOS 애플리케이션입니다.
+역 주변의 관광지, 맛집, 카페 등을 탐색하고 출발 시간에 맞춰 안전하게 플랫폼으로 돌아올 수 있도록 가이드합니다.
-### 프로젝트 생성
+> 💡 **우리는 왜 이 앱을 만들었을까요?**
+> 기차를 기다리는 시간, 그저 대기실에서 시간을 보내기엔 아깝지 않나요?
+> TimeSpot과 함께 여행의 시작부터 특별한 경험을 만들어보세요.
-```bash
-# TuistTool 컴파일 (최초 1회)
-swiftc TuistTool.swift -o make
+### 📱 스크린샷
-# 새 프로젝트 생성 (대화형)
-./make newproject
+
-# 또는 바로 설정
-./make newproject MyApp --bundle-id com.company.myapp
-```
+| 메인 화면 | 역 선택 | 주변 탐색 | 경로 안내 |
+|:---:|:---:|:---:|:---:|
+|

|

|

|

|
-### 개발 환경 설정
-```bash
-# Tuist 4.97.2 워크플로우
-./make build # clean → install → generate
-./make generate # 프로젝트 생성
-./make clean # 정리
-./make reset # 전체 캐시 리셋
-```
+
-## ⚙️ 개발 환경
+## ✨ 주요 기능
-- **iOS 17.0+** (Swift Concurrency 완전 지원)
-- **Xcode 26.0.1+**
-- **Swift 6.0+**
-- **Tuist 4.97.2**
+### 🚉 스마트한 여행 계획
+- **전국 주요 KTX역 지원**: 서울, 부산, 대전, 광주 등 전국 26개 역
+- **정확한 출발 시간 관리**: 다음날 23:59까지 자유로운 시간 설정
+- **대기 시간 계산**: 최소 20분 이상의 여유 시간 확보
-## 📚 사용 라이브러리
+### 🗺️ 주변 장소 탐색
+- **다양한 POI 정보**: 관광지, 맛집, 카페, 쇼핑, 문화시설 등
+- **실시간 위치 기반**: GPS를 활용한 정확한 주변 정보
+- **상세 정보 제공**: 영업시간, 리뷰, 연락처 등
-- **ComposableArchitecture**: 상태 관리
-- **TCACoordinators**: TCA 기반 네비게이션
-- **WeaveDI**: 의존성 주입
-- **Swift Concurrency**: Actor 기반 비동기 처리
+### 📍 똑똑한 길찾기
+- **NaverMap 연동**: 정확하고 빠른 경로 안내
+- **외부 앱 지원**: 네이버맵, 구글맵, 애플 지도 등
+- **실시간 소요 시간**: 도보 경로 및 예상 도착 시간
-## 🎯 주요 특징
+### ⏰ 알림 시스템
+- **15분 전**: "활동을 차분히 마무리해 주세요"
+- **10분 전**: "슬슬 일어날 준비를 해볼까요?"
+- **5분 전**: "출발 채비를 할 시간이에요"
+- **즉시 출발**: "지금 바로 출발해야 해요!"
+
+### 📊 여행 기록 관리
+- **방문 히스토리**: 다녀온 장소와 여행 기록 보관
+- **여정 추적**: 출발부터 복귀까지의 전체 여정 관리
+
+## 🏗 프로젝트 아키텍처
+
+### 🎯 Micro Feature Architecture with Tuist
-### 🏛️ Clean Architecture
```
-Presentation → Domain → Data
- ↓ ↓ ↓
- UI 로직 비즈니스 데이터
+TimeSpot-iOS/
+├── 📱 Projects/
+│ ├── App/ # 메인 애플리케이션 타겟
+│ │ └── Sources/
+│ │ ├── Application/ # AppDelegate, SceneDelegate
+│ │ └── Root/ # 루트 화면 설정
+│ │
+│ ├── Presentation/ # 🎨 UI Layer
+│ │ └── Home/ # 홈 기능 모듈
+│ │ ├── Sources/
+│ │ │ ├── Main/ # 메인 홈 화면
+│ │ │ ├── TrainStation/ # 역 선택
+│ │ │ ├── Explore/ # 주변 탐색
+│ │ │ ├── Route/ # 경로 안내
+│ │ │ ├── RouteNotification/ # 알림
+│ │ │ └── Components/ # 공통 컴포넌트
+│ │ ├── Tests/ # 단위 테스트
+│ │ └── Testing/ # 테스트 Mock
+│ │
+│ ├── Domain/ # 🔥 Business Logic Layer
+│ │ ├── Entity/ # 도메인 엔티티
+│ │ ├── UseCase/ # 비즈니스 로직 구현
+│ │ └── DomainInterface/ # 인터페이스 정의 (Protocol)
+│ │
+│ ├── Data/ # 📡 Data Layer
+│ │ ├── Service/ # REST API 서비스
+│ │ ├── Repository/ # Repository 구현체
+│ │ └── Model/ # DTO, Response Models
+│ │
+│ ├── Network/ # 🌐 Network Layer
+│ │ ├── Networks/ # 네트워크 설정
+│ │ ├── Foundations/ # 네트워크 유틸리티
+│ │ └── ThirdPartys/ # AsyncMoya, WeaveDI
+│ │
+│ └── Shared/ # 🔧 Shared Layer
+│ ├── DesignSystem/ # 디자인 시스템
+│ ├── Utill/ # 공통 유틸리티
+│ └── ThirdPartyLib/ # 외부 라이브러리 래핑
+│
+└── 🔧 Tuist/ # 프로젝트 설정
+ ├── Package.swift
+ └── ProjectDescriptionHelpers/
```
-### 🔄 의존성 방향
+### 🏛️ Clean Architecture Pattern
+
+```mermaid
+graph TD
+ A[🎨 Presentation Layer] --> B[🔥 Domain Layer]
+ B --> C[📡 Data Layer]
+ D[🌐 Network Layer] --> C
+ E[🔧 Shared Layer] --> A
+ E --> B
+ E --> C
+
+ A -.-> F[SwiftUI Views]
+ A -.-> G[TCA Reducers]
+ B -.-> H[Use Cases]
+ B -.-> I[Entities]
+ C -.-> J[Repositories]
+ C -.-> K[API Services]
+```
+
+### 🔄 의존성 방향 원칙
+
```
Presentation → Domain (UseCase Protocol)
↓
@@ -104,38 +146,189 @@ Data/Repository → Domain (Entity + Repository Protocol)
Data/Model → Domain (Entity 변환)
```
-**핵심 원칙:**
-- Presentation은 Domain의 UseCase Protocol만 의존
-- Domain은 외부 계층에 의존하지 않는 순수 비즈니스 로직
-- Data는 Domain의 Entity와 Repository Protocol을 구현
-- 모든 데이터 흐름은 Domain을 중심으로 진행
+**핵심 설계 원칙:**
+- ✅ **Presentation**은 Domain의 UseCase Protocol만 의존
+- ✅ **Domain**은 외부 계층에 의존하지 않는 순수 비즈니스 로직
+- ✅ **Data**는 Domain의 Entity와 Repository Protocol을 구현
+- ✅ 모든 데이터 흐름은 **Domain을 중심**으로 진행
+
+## 🛠 기술 스택
-### 🚀 Swift Concurrency
-- Actor 기반 Thread-Safe KeychainManager 구현
+### Core Technologies
+- **🎯 Architecture**: The Composable Architecture (TCA)
+- **📦 Modularization**: Tuist 4.97.2 (Micro Feature Architecture)
+- **💉 Dependency Injection**: WeaveDI
+- **🔀 Navigation**: TCA Navigation
+- **⚡ Concurrency**: Swift Concurrency (Actor 기반 비동기 처리)
-### 📦 Tuist 4.97.2 최적화
-- ✅ 새로운 `install` 명령어로 빠른 의존성 관리
-- ✅ 바이너리 캐시 활용으로 빌드 성능 향상
-- ✅ 암시적 의존성 자동 검사
+### Key Dependencies
+- **ComposableArchitecture**: 상태 관리 및 단방향 데이터 플로우
+- **TCACoordinators**: TCA 기반 네비게이션 시스템
+- **WeaveDI**: 의존성 주입 컨테이너
+- **Swift Concurrency**: Actor 기반 Thread-Safe 비동기 처리
+
+### UI & UX
+- **🎨 UI Framework**: SwiftUI
+- **🎨 Design System**: 커스텀 DesignSystem 모듈
+- **🖼️ Image Loading**: Kingfisher with 최적화
+
+### Networking & Data
+- **🌐 HTTP Client**: Moya + AsyncMoya
+- **📱 API Architecture**: RESTful API with JSON
+- **💾 Local Storage**: UserDefaults, Keychain (Actor 기반)
+- **📡 Real-time**: Push Notifications (APNs)
+
+### Maps & Location
+- **🗺️ Map Service**: Naver Maps SDK
+- **📍 Location**: Core Location Framework
+- **🛣️ Places**: Google Places API
+
+### Development Tools
+- **📊 Analytics**: 커스텀 로깅 시스템 (LogMacro)
+- **🔧 Build Tool**: Tuist + SPM
+- **🧪 Testing**: SwiftTesting + TCA Testing
+- **📱 Automation**: fastlane (스크린샷, 배포)
+- **⚡ Performance**: Swift Concurrency (async/await, Actor)
+
+## 🚀 빠른 시작
+
+### ✅ 필수 요구사항
+
+- **💻 Xcode**: 16.0 이상
+- **📱 iOS**: 17.0 이상
+- **⚡ Swift**: 6.0 이상
+- **🔧 Tuist**: 4.97.2 이상
+
+### 🛠 설치 및 실행
+
+#### 1️⃣ 저장소 클론
+```bash
+git clone https://github.com/Roy-wonji/TimeSpot-iOS.git
+cd TimeSpot-iOS
+```
+
+#### 2️⃣ Tuist 설치
+```bash
+curl -Ls https://install.tuist.io | bash
+```
+
+#### 3️⃣ 프로젝트 빌드 및 생성
+```bash
+# 전체 워크플로우 (권장)
+./make build # clean → install → generate
+
+# 또는 단계별 실행
+./make clean # 기존 파일 정리
+./make install # 의존성 설치
+./make generate # 프로젝트 생성
+```
+
+#### 4️⃣ Xcode에서 실행
+```bash
+open TimeSpot.xcworkspace
+```
+
+### ⚙️ 환경 설정
+
+프로젝트 실행을 위해 다음 API 키가 필요합니다:
+
+```swift
+// Config.swift에서 설정
+enum APIKeys {
+ static let naverMapsClientID = "YOUR_NAVER_MAPS_KEY"
+ static let googlePlacesAPI = "YOUR_GOOGLE_PLACES_KEY"
+ static let timeSpotServerURL = "YOUR_SERVER_URL"
+}
+```
## 🛠️ 주요 명령어
-### 기본 워크플로우
+### 🔄 기본 워크플로우
```bash
-./make build # 전체 빌드 (권장)
+./make build # 전체 빌드 프로세스 (권장)
./make generate # 프로젝트 생성만
-./make moduleinit # 새 모듈 생성
+./make moduleinit # 새 모듈 생성 (대화형)
```
-### 문제 해결
+### 🚨 문제 해결
```bash
-./make reset # 강력한 클린 + 재생성
+./make reset # 강력한 클린 + 캐시 삭제 + 재생성
+./make clean # 빌드 아티팩트 정리
./make install # 의존성 재설치
```
-### 코드 품질
+### 🔍 코드 품질 관리
```bash
-./make inspect-imports # 의존성 검사
-./make inspect-coverage # 코드 커버리지
+./make inspect-imports # 모듈 의존성 검사
+./make inspect-coverage # 코드 커버리지 분석
+./make graph # 의존성 그래프 생성
```
+### 📦 모듈 관리
+```bash
+./make moduleinit # 새 Feature 모듈 생성
+./make test # 전체 테스트 실행
+```
+
+### 📱 스크린샷 자동 생성 (fastlane)
+```bash
+fastlane snapshot # 전체 스크린샷 생성
+fastlane snapshot --scheme TimeSpot # 특정 스킴만
+```
+
+## 📋 사용법
+
+### 1️⃣ 여행 계획 설정
+1. **출발역 선택**: 전국 26개 주요 KTX역 중 선택
+2. **출발 시간 설정**: 현재 시각부터 다음날 23:59까지
+3. **대기 시간 확인**: 최소 20분 이상의 여유 시간 필요
+
+### 2️⃣ 주변 장소 탐색
+1. **"주변 탐색 시작하기"** 버튼 터치
+2. **위치 권한** 허용 (정확한 주변 정보 제공을 위해 필요)
+3. **카테고리별 탐색**: 관광지 🏛️, 맛집 🍴, 카페 ☕, 쇼핑 🛍️ 등
+
+### 3️⃣ 스마트한 경로 안내
+1. **장소 선택**: 방문하고 싶은 장소를 선택
+2. **"길찾기 시작"**: 버튼을 터치하여 여정 시작
+3. **외부 앱 연동**: 선호하는 지도 앱으로 실제 네비게이션
+
+### 4️⃣ 안전한 복귀 가이드
+- **📱 스마트 알림**: 출발 시간에 맞춰 단계별 알림
+- **⏰ 실시간 추적**: 현재 위치에서 역까지의 실시간 경로
+- **🔔 맞춤 알림**: 개인 일정에 맞춘 최적의 출발 타이밍
+
+
+## 📄 라이선스
+
+이 프로젝트는 **MIT 라이선스** 하에 배포됩니다.
+자세한 내용은 [LICENSE](LICENSE) 파일을 참고하세요.
+
+## 👥 팀 & 크레딧
+
+### 💻 개발팀
+- **iOS Developer & Architecture**: 서원지 ([@Roy-wonji](https://github.com/Roy-wonji))
+- **Backend Developer**: [@loadingKKamo21](https://github.com/loadingKKamo21)
+- **Designer**: 박미란
+- **Product Manager**: 전희정
+
+
+## 📞 문의 및 지원
+
+- 📧 **이메일**: suhwj81@gmail.com
+- 🐛 **버그 신고**: [Issues](https://github.com/Roy-wonji/TimeSpot-iOS/issues)
+- 💡 **기능 제안**: [Discussions](https://github.com/Roy-wonji/TimeSpot-iOS/discussions)
+- 📱 **App Store**: [TimeSpot 다운로드](#)
+
+---
+
+
+
+**Made with ❤️ by SWYP Team**
+
+*여행의 시작을 특별하게, TimeSpot과 함께하세요*
+
+[](https://github.com/Roy-wonji/TimeSpot-iOS)
+
+
+
diff --git a/Tuist/Package.swift b/Tuist/Package.swift
index 50cdce0..18d39d5 100644
--- a/Tuist/Package.swift
+++ b/Tuist/Package.swift
@@ -21,7 +21,8 @@ let packageSettings = PackageSettings(
"Clocks": .staticFramework,
"ConcurrencyExtras": .staticFramework,
"WeaveDI": .staticFramework,
- "ReactiveSwift": .staticFramework
+ "ReactiveSwift": .staticFramework,
+ "SDWebImageSwiftUI": .staticFramework
]
)
#endif
@@ -36,5 +37,8 @@ let package = Package(
.package(url: "https://github.com/Roy-wonji/AsyncMoya", from: "1.1.8"),
.package(url: "https://github.com/openid/AppAuth-iOS.git", from: "2.0.0"),
.package(url: "https://github.com/ReactiveCocoa/ReactiveSwift.git", from: "6.7.0"),
+ .package(url: "https://github.com/onevcat/Kingfisher.git", from: "8.2.0"),
+ .package(url: "https://github.com/firebase/firebase-ios-sdk.git", exact: "12.7.0"),
+ .package(url: "https://github.com/SDWebImage/SDWebImageSwiftUI.git", from: "2.0.0"),
]
)
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 5d556fd..cb9741b 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -36,6 +36,33 @@ platform :ios do
in_house: false
)
+ # 자동으로 빌드 번호 증가
+ current_build_number = latest_testflight_build_number(
+ app_identifier: BUNDLE_ID,
+ platform: "ios"
+ )
+ new_build_number = current_build_number + 1
+ puts "🔢 Current build number: #{current_build_number}"
+ puts "🔢 New build number: #{new_build_number}"
+
+ # Extension+String.swift 파일에서 빌드 번호 업데이트
+ extension_file_path = "../Plugins/ProjectTemplatePlugin/ProjectDescriptionHelpers/Project+Templete/Extension+String.swift"
+ content = File.read(extension_file_path)
+
+ # 빌드 번호 라인 수정
+ updated_content = content.gsub(/public static func appBuildVersion\(buildVersion: String = "\d+"\) -> String \{/,
+ "public static func appBuildVersion(buildVersion: String = \"#{new_build_number}\") -> String {")
+
+ File.write(extension_file_path, updated_content)
+ puts "✅ Updated build number to #{new_build_number} in Extension+String.swift"
+
+ # Tuist 프로젝트 재생성
+ Dir.chdir("..") do
+ puts "🔧 Regenerating Tuist workspace with new build number..."
+ sh("tuist generate --no-open")
+ puts "✅ Tuist workspace regenerated"
+ end
+
match(
type: "appstore",
readonly: true,
@@ -44,6 +71,7 @@ platform :ios do
app_identifier: ["io.TimeSpot.co"]
)
+ ipa_path = nil
# Change to project root directory
Dir.chdir("..") do
puts "📁 Current directory: #{Dir.pwd}"
@@ -123,7 +151,7 @@ platform :ios do
upload_to_testflight(
ipa: ipa_path,
changelog: "변경사항",
- groups: ["TimeSpot"],
+ groups: ["TimeSpot", "timeSpot"],
beta_app_description: "TimeSpot 앱입니다.",
notify_external_testers: true,
skip_waiting_for_build_processing: true,
@@ -144,14 +172,35 @@ platform :ios do
in_house: false
)
- # 자동으로 빌드 번호 증가
- current_build_number = latest_testflight_build_number(
- app_identifier: BUNDLE_ID,
- platform: "ios"
- )
+ # QA와 동일한 빌드 번호 자동 증가 로직
+ begin
+ current_build_number = latest_testflight_build_number(
+ app_identifier: BUNDLE_ID,
+ platform: "ios"
+ )
+ puts "📱 TestFlight 최신 빌드 번호: #{current_build_number}"
+ rescue => e
+ puts "⚠️ TestFlight 빌드 번호 조회 실패, 기본값 1 사용: #{e.message}"
+ current_build_number = 1
+ end
+
+ # App Store 라이브 버전 빌드 번호도 확인
+ begin
+ live_build_number = app_store_build_number(
+ app_identifier: BUNDLE_ID,
+ platform: "ios"
+ )
+ puts "🏪 App Store 라이브 빌드 번호: #{live_build_number}"
+
+ # 더 높은 빌드 번호 사용
+ current_build_number = [current_build_number, live_build_number].max
+ rescue => e
+ puts "⚠️ App Store 빌드 번호 조회 실패: #{e.message}"
+ end
+
new_build_number = current_build_number + 1
- puts "🔢 Current build number: #{current_build_number}"
- puts "🔢 New build number: #{new_build_number}"
+ puts "🔢 현재 최고 빌드 번호: #{current_build_number}"
+ puts "🔢 새로운 빌드 번호: #{new_build_number}"
# Extension+String.swift 파일에서 빌드 번호 업데이트
extension_file_path = "../Plugins/ProjectTemplatePlugin/ProjectDescriptionHelpers/Project+Templete/Extension+String.swift"
@@ -162,14 +211,15 @@ platform :ios do
"public static func appBuildVersion(buildVersion: String = \"#{new_build_number}\") -> String {")
File.write(extension_file_path, updated_content)
- puts "✅ Updated build number to #{new_build_number} in Extension+String.swift"
+ puts "✅ 빌드 번호를 #{new_build_number}로 업데이트 완료"
# Tuist 프로젝트 재생성
Dir.chdir("..") do
- puts "🔧 Regenerating Tuist workspace with new build number..."
+ puts "🔧 Tuist workspace 재생성 중..."
sh("tuist generate --no-open")
- puts "✅ Tuist workspace regenerated"
+ puts "✅ Tuist workspace 재생성 완료"
end
+
match(
type: "appstore",
readonly: true,
@@ -178,29 +228,82 @@ platform :ios do
app_identifier: ["io.TimeSpot.co"]
)
- ipa_path = build_app(
- workspace: "#{APP_RELEASE_NAME}.xcworkspace",
- scheme: "TimeSpot-Prod",
- configuration: "Release",
- output_directory: OUTPUT_DIR,
- output_name: IPA_FILENAME,
- export_method: "app-store",
- clean: true,
- silent: false,
- verbose: true,
- xcargs: "CODE_SIGN_IDENTITY='Apple Distribution' CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM=#{TEAM_ID} " +
- "COMPILER_INDEX_STORE_ENABLE=NO ENABLE_BITCODE=NO " +
- "SWIFT_COMPILATION_MODE=wholemodule " +
- "-allowProvisioningUpdates",
- export_options: {
- signingStyle: "manual",
- uploadBitcode: false,
- teamID: TEAM_ID,
- provisioningProfiles: {
- "#{BUNDLE_ID}" => "match AppStore #{BUNDLE_ID}"
+ ipa_path = nil
+ # QA와 동일한 workspace 처리 로직
+ Dir.chdir("..") do
+ puts "📁 현재 디렉토리: #{Dir.pwd}"
+ puts "📋 사용 가능한 파일들: #{Dir.entries('.')}"
+
+ # Try to generate workspace if missing
+ workspace_files = Dir.glob("*.xcworkspace")
+ if workspace_files.empty?
+ puts "🔧 workspace가 없습니다, 생성 중..."
+
+ # Check if tuist is available
+ tuist_available = system("which tuist > /dev/null 2>&1")
+ puts "Tuist 사용 가능: #{tuist_available}"
+
+ unless tuist_available
+ puts "🔧 brew로 tuist 설치 중..."
+ sh("brew install tuist")
+ end
+
+ begin
+ if File.exist?("make")
+ puts "🔧 ./make install 실행 중..."
+ sh("./make install")
+ puts "🔧 ./make generate 실행 중..."
+ sh("./make generate")
+ else
+ puts "🔧 tuist 직접 실행 중..."
+ sh("tuist install")
+ sh("tuist generate --no-open")
+ end
+ rescue => e
+ puts "❌ 생성 실패: #{e.message}"
+ end
+
+ workspace_files = Dir.glob("*.xcworkspace")
+ puts "🔍 발견된 workspace 파일들: #{workspace_files}"
+ end
+
+ if workspace_files.empty?
+ puts "❌ workspace를 찾을 수 없습니다!"
+ puts "🔍 디렉토리 내 모든 파일:"
+ Dir.entries('.').each { |f| puts " #{f}" }
+ UI.user_error!("workspace 파일을 생성할 수 없습니다. tuist 설정과 플러그인을 확인해주세요.")
+ end
+
+ workspace_name = workspace_files.first
+ workspace_path = File.expand_path(workspace_name)
+ puts "✅ 사용할 workspace: #{workspace_name}"
+ puts "✅ 전체 workspace 경로: #{workspace_path}"
+
+ ipa_path = build_app(
+ workspace: workspace_path,
+ scheme: "TimeSpot-Prod",
+ configuration: "Release",
+ export_method: "app-store",
+ output_directory: File.expand_path("../#{OUTPUT_DIR}"),
+ output_name: IPA_FILENAME,
+ clean: false,
+ silent: true,
+ xcargs: "CODE_SIGN_IDENTITY='Apple Distribution' CODE_SIGN_STYLE=Manual DEVELOPMENT_TEAM=#{TEAM_ID} " +
+ "COMPILER_INDEX_STORE_ENABLE=NO ENABLE_BITCODE=NO " +
+ "SWIFT_COMPILATION_MODE=wholemodule -parallelizeTargets " +
+ "ENABLE_PARALLEL_SIGNING=YES DISABLE_MANUAL_TARGET_ORDER_BUILD_WARNING=YES " +
+ "FRAMEWORK_SEARCH_PATHS='$(inherited)' LIBRARY_SEARCH_PATHS='$(inherited)' " +
+ "-allowProvisioningUpdates -quiet",
+ export_options: {
+ signingStyle: "manual",
+ uploadBitcode: false,
+ teamID: TEAM_ID,
+ provisioningProfiles: {
+ "#{BUNDLE_ID}" => "match AppStore #{BUNDLE_ID}"
+ }
}
- }
- )
+ )
+ end
# clean_symbols_from_ipa(ipa_path: ipa_path)
@@ -226,6 +329,7 @@ platform :ios do
UI.important(" 1. https://appstoreconnect.apple.com 접속")
UI.important(" 2. TimeSpot 앱 선택")
UI.important(" 3. 버전 #{options[:version]} 심사 상태 확인")
+ UI.important(" 4. 빌드 번호: #{new_build_number}")
UI.important("")
UI.success("✅ 빌드, 업로드, 심사 요청이 모두 성공적으로 완료되었습니다!")
UI.success("🚀 이제 Apple의 심사를 기다리기만 하면 됩니다!")
diff --git a/fastlane/README.md b/fastlane/README.md
new file mode 100644
index 0000000..25c3781
--- /dev/null
+++ b/fastlane/README.md
@@ -0,0 +1,59 @@
+fastlane documentation
+----
+
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```sh
+xcode-select --install
+```
+
+For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
+
+# Available Actions
+
+### tdd_ci
+
+```sh
+[bundle exec] fastlane tdd_ci
+```
+
+TDD 테스트 및 자동 배포
+
+----
+
+
+## iOS
+
+### ios QA
+
+```sh
+[bundle exec] fastlane ios QA
+```
+
+Upload to TestFlight (Debug)
+
+### ios release
+
+```sh
+[bundle exec] fastlane ios release
+```
+
+Submit to App Store
+
+### ios submit_for_review
+
+```sh
+[bundle exec] fastlane ios submit_for_review
+```
+
+Submit already uploaded version for review
+
+----
+
+This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
+
+More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
+
+The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/fastlane/metadata/copyright.txt b/fastlane/metadata/copyright.txt
new file mode 100644
index 0000000..9aea452
--- /dev/null
+++ b/fastlane/metadata/copyright.txt
@@ -0,0 +1 @@
+@TimeSpot
diff --git a/fastlane/metadata/ko/apple_tv_privacy_policy.txt b/fastlane/metadata/ko/apple_tv_privacy_policy.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/apple_tv_privacy_policy.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/ko/description.txt b/fastlane/metadata/ko/description.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/description.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/ko/keywords.txt b/fastlane/metadata/ko/keywords.txt
new file mode 100644
index 0000000..015da47
--- /dev/null
+++ b/fastlane/metadata/ko/keywords.txt
@@ -0,0 +1 @@
+타임스팟, 여랭, TIMESPOT, timespot, TimeSpot , 주변역 둘러볼때
diff --git a/fastlane/metadata/ko/marketing_url.txt b/fastlane/metadata/ko/marketing_url.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/marketing_url.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/ko/name.txt b/fastlane/metadata/ko/name.txt
new file mode 100644
index 0000000..ed6012c
--- /dev/null
+++ b/fastlane/metadata/ko/name.txt
@@ -0,0 +1 @@
+TimeSpot
diff --git a/fastlane/metadata/ko/privacy_url.txt b/fastlane/metadata/ko/privacy_url.txt
new file mode 100644
index 0000000..6352bab
--- /dev/null
+++ b/fastlane/metadata/ko/privacy_url.txt
@@ -0,0 +1 @@
+https://www.notion.so/329f94ae438b807d95dcd0f5f8abf66a?source=copy_link
diff --git a/fastlane/metadata/ko/promotional_text.txt b/fastlane/metadata/ko/promotional_text.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/promotional_text.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/ko/release_notes.txt b/fastlane/metadata/ko/release_notes.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/release_notes.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/ko/subtitle.txt b/fastlane/metadata/ko/subtitle.txt
new file mode 100644
index 0000000..443e8dc
--- /dev/null
+++ b/fastlane/metadata/ko/subtitle.txt
@@ -0,0 +1 @@
+대기시간 활용 · 기차여행 · 역 근처 추천
diff --git a/fastlane/metadata/ko/support_url.txt b/fastlane/metadata/ko/support_url.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/ko/support_url.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/primary_category.txt b/fastlane/metadata/primary_category.txt
new file mode 100644
index 0000000..bed7bef
--- /dev/null
+++ b/fastlane/metadata/primary_category.txt
@@ -0,0 +1 @@
+TRAVEL
diff --git a/fastlane/metadata/primary_first_sub_category.txt b/fastlane/metadata/primary_first_sub_category.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/primary_first_sub_category.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/primary_second_sub_category.txt b/fastlane/metadata/primary_second_sub_category.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/primary_second_sub_category.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/review_information/demo_password.txt b/fastlane/metadata/review_information/demo_password.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/review_information/demo_password.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/review_information/demo_user.txt b/fastlane/metadata/review_information/demo_user.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/review_information/demo_user.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/review_information/email_address.txt b/fastlane/metadata/review_information/email_address.txt
new file mode 100644
index 0000000..f270004
--- /dev/null
+++ b/fastlane/metadata/review_information/email_address.txt
@@ -0,0 +1 @@
+shuwj81@icloud.com
diff --git a/fastlane/metadata/review_information/first_name.txt b/fastlane/metadata/review_information/first_name.txt
new file mode 100644
index 0000000..1ef1d2f
--- /dev/null
+++ b/fastlane/metadata/review_information/first_name.txt
@@ -0,0 +1 @@
+원지
diff --git a/fastlane/metadata/review_information/last_name.txt b/fastlane/metadata/review_information/last_name.txt
new file mode 100644
index 0000000..a963e41
--- /dev/null
+++ b/fastlane/metadata/review_information/last_name.txt
@@ -0,0 +1 @@
+서
diff --git a/fastlane/metadata/review_information/notes.txt b/fastlane/metadata/review_information/notes.txt
new file mode 100644
index 0000000..d22cca7
--- /dev/null
+++ b/fastlane/metadata/review_information/notes.txt
@@ -0,0 +1 @@
+애플 또는 비회원로그인 처리 가능 합니다
diff --git a/fastlane/metadata/review_information/phone_number.txt b/fastlane/metadata/review_information/phone_number.txt
new file mode 100644
index 0000000..407eae8
--- /dev/null
+++ b/fastlane/metadata/review_information/phone_number.txt
@@ -0,0 +1 @@
++82 1094375187
diff --git a/fastlane/metadata/secondary_category.txt b/fastlane/metadata/secondary_category.txt
new file mode 100644
index 0000000..cc52552
--- /dev/null
+++ b/fastlane/metadata/secondary_category.txt
@@ -0,0 +1 @@
+LIFESTYLE
diff --git a/fastlane/metadata/secondary_first_sub_category.txt b/fastlane/metadata/secondary_first_sub_category.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/secondary_first_sub_category.txt
@@ -0,0 +1 @@
+
diff --git a/fastlane/metadata/secondary_second_sub_category.txt b/fastlane/metadata/secondary_second_sub_category.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fastlane/metadata/secondary_second_sub_category.txt
@@ -0,0 +1 @@
+
diff --git a/graph.png b/graph.png
index bc93c04..d3d0a3d 100644
Binary files a/graph.png and b/graph.png differ