Skip to content

Quaker-Lee/TaxRefundCalculator

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

319 Commits
 
 
 
 
 
 
 
 

Repository files navigation

TaxRefundCalculator

92a50ef1a16e710f


📦 How to Install

클릭 시 앱스토어로 이동합니다.


📱 프로젝트 소개

택스리펀 계산기는 해외여행 중 발생하는 부가세 환급(Tax Refund)을 당일 환율로 쉽게 계산해주는 앱입니다.

  • 구매금액 입력만으로 환급 예상 금액과 내 화폐 기준 가격을 확인 가능
  • 환급액 기록 및 여행별 지출 정리
  • 8개 언어 지원 / 173개국 출시

👥 팀원 소개

Names GitHub Parts
이재건 @Quaker-Lee 시작화면, 계산화면, 설정화면, 프로젝트 초기 세팅, 앱배포
나영진 @bryjna07 기록화면, 환율화면, 파이어베이스 세팅

📅 프로젝트 기간

개발 - 2025.04.28 ~ 2025.06.27
업데이트 - 2025.06.27 ~ ing
리팩토링 - 2025.07.14 ~ ing


⚡️ 주요 기능

🌍 글로벌 173개국 지원

  • 전 세계 173개국에서 자유롭게 사용 가능
  • 각 국가별 통화 및 환급(부가가치세/VAT) 정책 반영
  • 다양한 언어와 국가별 환경에 최적화된 사용자 경험 제공

💱 당일 환율 자동 적용

  • 매일 최신 환율 데이터를 자동 반영
  • Firebase를 통한 신뢰성 높은 환율 정보 제공
  • 구매금액, 환급금, 환급 후 실수령 금액을 내가 사용하는 화폐로 즉시 확인

🧮 초간단 택스리펀 계산

  • 구매금액만 입력하면 예상 환급액과 실제 내 화폐로 환급받을 금액을 즉시 확인
  • 각 국가의 VAT(부가세) 정책에 맞춘 환급액 자동 계산
  • 복잡한 공식이나 수식 없이 누구나 쉽게 사용 가능

🗂️ 여행 지출 및 환급 내역 기록/관리

  • 구매한 물품별로 기록을 남겨 여행 전체 지출 및 환급액을 한눈에 파악
  • 나라별·여행별로 기록을 분류하여 체계적으로 관리
  • 총 지출 금액, 총 환급액 등 여행 경비를 쉽게 확인

🌐 다국어 완전 지원 & 직관적 UI/UX

  • 한국어, 영어, 일본어, 스페인어, 독일어, 프랑스어, 이탈리아어, 러시아어 등 8개 언어 지원
  • 모든 화면과 안내 메시지가 현지 언어로 자연스럽게 제공
  • 소형 기기(아이폰 SE 등) 완벽 지원
  • 다크모드 및 접근성 기능 제공

🔒 개인정보 미수집 & 안전한 사용

  • 사용자 개인정보를 절대 수집, 저장, 전송하지 않음
  • 모든 기록은 오직 로컬(사용자 기기)에서만 관리
  • App Store 개인정보 보호 가이드라인 100% 준수

✈️ 여행자 맞춤 기능

  • 기준 통화와 여행 국가의 중복 선택 방지
  • 실시간 입력값 검증으로 입력 실수 최소화
  • 각 국가별 숫자 표기법/통화 단위 로컬라이징
  • 쉽고 빠른 국가, 통화, 언어 선택 및 자동 저장

🛠 기술 스택

프레임워크 및 라이브러리

  • UIKit: 인터페이스 구현
  • SnapKit: 코드 기반 AutoLayout
  • Then: 선언형 UI 구성
  • Firebase Firestore: 데이터베이스
  • Combine: 비동기 데이터 스트림 및 이벤트 처리
  • RxSwift + RxCocoa: 비동기 스트림 처리 및 UI 반응형 바인딩
  • UserDefaults: 로컬 저장소 관리

디자인 패턴

  • Protocol-Delegate: 모달 및 팝업 데이터 전달
  • MVVM: 화면(View)과 데이터(Model) 분리, ViewModel을 통한 데이터 바인딩
  • Singleton: 전역에서 단 하나의 인스턴스만 사용

API

  • FreeCurrencyAPI: 실시간 환율 API

🛠 개발 환경

  • iOS 16.0+
  • Swift 5.0+

🧠 프로젝트 아키텍처 (MVVM)

스크린샷 2025-07-06 오후 8 27 23

📦 ViewModel별 의존성 요약

ViewModel 사용하는 모델/서비스
StartVM ExchangeRateAPIService, ExchangeSyncManager, FirebaseExchangeService, RefundCondition, CurrencyDisplayUnit
CalculateVM SavedCard, RefundCondition, CurrencyDisplayUnit, SaveUserDefaults
SavedVM SavedCard, SaveUserDefaults
SavedModalVM SavedCard, SaveUserDefaults, RefundCondition
ExchangeVM FirebaseExchangeService, CurrencyDisplayUnit
SettingVM ExchangeRateAPIService, FirebaseExchangeService, SaveUserDefaults

🌏 구현 내용

🚀 SceneDelegate, ExchangeSyncManager

  • 사용 기술: RxSwift, FirebaseFireStore, FreeCurrencyAPI
  • 앱 실행 시, ExchangeSyncManager(싱글톤)가 RxSwift 기반 비동기 체인(.flatMap, .catch, .subscribe 등 연산자 활용)으로 환율 데이터 동기화 수행
    • 오늘 날짜와 Firebase 내 환율 데이터 날짜를 비교,
      오늘 데이터가 없는 경우에만 API 호출 → Firebase 업데이트

🏁 시작화면 StartPage

  • 사용 기술: MVVM + RxSwift, RxCocoa, FirebaseFireStore, FreeCurrencyAPI
  • 기준 화폐·여행 국가 선택 → 환율/환급조건 안내
    • 국기-정책 매칭(getRefundPolicy, RefundCondition.flagToPolicyMap)
  • RxSwift BehaviorRelay를 활용, 환율 정보와 안내문 텍스트 실시간 바인딩

🧮 계산화면 CalculatePage

  • 사용 기술: MVVM + Combine, 사용자 입력 검증, UserDefaults
  • 구매 금액 입력 → 해당 국가 부가세율 기반 환급액 자동 계산
  • isValidFloatingPoint로 실시간 입력 제한
  • 천 단위/소수점 등 국가별 포맷 파싱(parseLocalizedNumber), 유럽식/영미식 등 자동 대응
  • 환급액 계산, 환급액 환산, 저장 로직 분리
  • 결과는 기준 화폐로 환산, 구매/환급/변환 금액 등 전체 상태를 SavedCard에 저장
  • 저장·표시 전 포맷 가공(roundedString)
  • SettingPage에서 화폐/국가 변경 시 Combine 기반으로 UI 자동 갱신

🗂️ 기록화면 SavedPage

  • 사용 기술: MVVM + RxSwift, RxCocoa, UserDefaults + Codable, Fastis
  • Rx 상태관리, 저장 기록 리스트 출력
  • Fastis 라이브러리로 날짜·화폐별 동시 필터링(RxCombineLatest 활용)
  • 기록 상세정보 모달에서 저장 당시 환율·환급 조건 제공
  • 화폐별 분류 및 총액 합산 기능 지원

💱 환율화면 ExchangePage

  • 사용 기술: MVVM + RxSwift, RxCocoa, Combine, FirebaseFireStore
  • 기준 화폐/여행 국가 변경 시 실시간 환율 갱신 (Combine, Rx 혼합 구조)
  • Firebase에 저장된 환율 기반, 필요 시 API 자동 갱신
  • 주요 통화코드 우선 정렬 및 국가별 표기 대응
    • Double+Formatted로 포맷 대응, 환율 표시는 항상 2자리 소수점

⚙️ 설정화면 SettingPage

  • 사용 기술: MVVM + RxSwift, Combine, FirebaseFireStore, UserDefaults, UIKit 다크모드
  • 기준 통화, 여행국가 변경 시 환율정보 연동 관리
  • SettingVM.shared 싱글톤 형태로 전역 관리
  • Combine, Rx 동시 사용(호환성/호출 예시 등)
  • 다크모드 값 변경 시 즉시 반영, 기록 삭제·초기화 기능(UserDefaults 리셋)

🔢 Double+Formatted

  • Double 확장으로 국가별 로케일/천 단위/소수점 구분자 자동 반영
  • 국가별로 소수점 이하 자리수 지정 가능(기본 2자리)
  • 소수점 이하가 0인 경우, 소수점 및 0 제거

🌐 Localizable

  • 8개 언어, 정책·환율 안내·에러 안내 등 전 UI 다국어화
  • 포맷 문자열(최소 금액/통화/환급율 등)도 현지화, 인자순서 국가별로 조정

📡 데이터 흐름

📌 앱 실행 시 초기 환율 동기화

앱이 시작될 때, ExchangeSyncManager를 통해 오늘 날짜 기준 환율 데이터를 Firebase에서 조회합니다.

  • ✅ 데이터 존재 → 아무 동작 없음
  • ❌ 데이터 없음 → 외부 환율 API에서 요청 후 Firebase에 저장
스크린샷 2025-07-06 오후 8 56 43

📌 사용자 상호작용 – 기준 통화 및 여행 국가 선택

사용자가 기준 통화 또는 여행 국가를 선택하면, Firebase에서 동기화된 환율을 기반으로 당일 환율을 표시합니다.

스크린샷 2025-07-06 오후 8 37 09

🗂 프로젝트 폴더 구조

TaxRefundCalculator/
├── Application/              # AppDelegate, SceneDelegate
├── Resources/                # Assets, LaunchScreen
├── SupportingFiles/          # Info.plist, GoogleService-Info.plist
├── API/                      # API 통신 계층
├── CalculatePage/            # 계산 화면
├── ExchangePage/             # 환율 화면
├── Extension/                # UIView 관련 확장
├── Modals/                   # 팝업 모달
├── Models/                   # 데이터 모델
├── SavedPage/                # 저장된 계산 기록
├── SettingPage/              # 설정
├── StartPage/                # 앱 시작 화면
├── TabBar/                   # 탭바 컨트롤러
├── Utils/                    # 유틸리티
└── Localizable/              # 다국어 지원

🔨 Trouble Shooting

🚀 API 요청 최소화 및 환율 표시 최적화

🔍 원인

  • API 비용 절감 및 트래픽 최소화를 위해 파이어베이스에 USD 기준 환율만 저장
  • 하지만, 사용자가 기준 통화를 변경할 때 즉시 다양한 기준 환율로 환산/표시해야 하는 복잡성 발생

해결 방안

  1. displayUnit 등 통화별 표준 단위 로직 설계
  2. 선택 기준 통화에 맞게 실시간 변환하는 함수화
  3. 모든 환율 표기를 Double+Formatted로 일관성 있게 출력

🔥 개선 효과

  • 서버 부하 없이 다양한 통화 기준으로 환율 신속 제공
  • 글로벌/다국적 사용자 환경에 실시간 맞춤 환율 노출
  • 유지보수 및 성능, 신뢰도 동시 확보

🚀 국가별 숫자 포맷 인식 오류

🔍 원인

  • 영미식(1,234.56)·유럽식(1.234,56) 등
  • 다양한 숫자 표기법이 혼재된 환경에서 기존에는 단순히 콤마(,)만 제거하고 Double로 변환했기 때문에
  • 일부 국가에서는 숫자 파싱 및 계산이 제대로 되지 않거나 잘못된 결과가 발생.

해결 방안

  1. NumberFormatter를 활용해 Locale.current 및 주요 국가 로케일에 따라
    • 천 단위/소수점 구분자를 자동 인식하도록 parseLocalizedNumber 함수 구현
  2. 계산/저장/표시 등 모든 과정에서 로케일에 맞는 포맷 일관성 유지
  3. 전 세계 국가의 표기법을 완벽하게 대응

🔥 개선 효과

  • 영미식, 유럽식, 그 외 표기법까지 모든 글로벌 사용자에게 일관된 숫자 인식 및 계산 정확도 보장
  • 숫자 관련 문의/오류 감소, 글로벌 신뢰성 강화

🚀 로케일(언어·국가)별 텍스트 인자 순서 오류

🔍 원인

  • NSLocalizedString 포맷 인자(예: %1$@, %2$@)의
  • 국가별 순서 차이로 인해 언어에 따라 안내문이나 환급조건 표시가
  • 의도와 다르게 표시되는 이슈 발생

해결 방안

  1. 각 언어별 Localizable.strings에서 포맷 인자의 순서를 명확히 구분(%1$@ 등 사용)
  2. 모든 언어별 포맷을 점검하고 인자 위치 통일
  3. 코드 리뷰 및 PR 단계에서 인자 순서, UI 표시 검증 프로세스 추가

🔥 개선 효과

  • 어떤 언어를 선택해도 정확한 안내문, 환급 조건 노출
  • 다국어 UX 품질 상승, 오역/오표시로 인한 혼란 방지

🚀 모달(시트) 하단 여백 및 리스트 위치 트러블슈팅 (링크)

🔍 원인

  • UISheetPresentationController의 레이아웃 시스템과 UITableView의 초기 콘텐츠 오프셋 동기화 이슈
  • 시트와 테이블뷰의 레이아웃 적용 시점이 달라 하단 여백이 어긋나거나 리스트/버튼이 잘리는 현상 발생

✅ 해결 방안

  1. 시트(Sheet) 레이아웃과 테이블뷰의 contentInset/contentOffset을 SafeArea 및 시트 크기에 맞게 동적으로 조정
  2. 뷰 레이아웃 완료 후(예: viewDidLayoutSubviews) 명시적으로 동기화 처리 로직 추가

🔥 개선 효과

  • 모든 기기에서 모달 하단 여백 및 리스트 위치가 정상적으로 표시됨
  • UI 깨짐, 겹침 등 사용자 경험 이슈 근본적으로 해결

🚀 금액 입력의 콤마(,)로 인한 계산 오류 트러블슈팅 (링크)

🔍 원인

  • 금액 입력값에 ,(콤마)가 포함되어 있을 때 (예: "1,000" 등)
  • Swift에서 해당 값을 Double로 변환 시 변환 실패로 인해 계산 로직이 제대로 동작하지 않음

✅ 해결 방안

  1. 입력값에서 콤마(, )를 제거 후 숫자 타입(Double)으로 변환하도록 로직 수정
  2. 예시 코드
let pureNumber = input.replacingOccurrences(of: ",", with: "")
let amount = Double(pureNumber)
  1. 모든 금액 입력 필드에 동일하게 적용

🔥 개선 효과

  • 금액 입력 시 콤마가 포함되어도 정상적으로 계산
  • 입력/계산 오류 완전 해결
  • 사용자 경험 및 서비스 신뢰도 향상

📝 Git Convention

커밋 메시지
  • Feat: 새로운 기능 추가
  • Fix: 버그 수정
  • Docs: 문서 수정
  • Style: 코드 포맷팅
  • Refactor: 코드 리팩토링
  • Test: 테스트 코드
  • Chore: 기타 변경사항
  • Cmt: 주석 수정
PR 규칙
  • PR 탬플릿 준수
  • 머지 전 팀원의 승인 필요
  • 기능별 스크린샷 첨부

📈 업데이트

v1.0.0

v1.0.1

v1.0.2

v1.0.3

v1.0.4

v1.0.5

v1.0.6

About

택스프리 계산기 / Tax Refund Calculator

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Swift 100.0%