0d7e9ba4f5
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
6.1 KiB
6.1 KiB
iOS 하이브리드 앱 (Capacitor)
Vue dist 를 네이티브 WebView로 패키징해 iOS 앱으로 빌드합니다. 안드로이드와 동일 코드베이스이며, 플랫폼 분기는 Capacitor.isNativePlatform() / getPlatform() === 'ios' 로 처리합니다.
구성
capacitor.config.json— appIdkr.sblog.slimbudget(안드와 동일), appName돈돼지 가계부, webDirdistios/— 네이티브 프로젝트(커밋됨, 빌드 산출물ios/App/build·Pods는 .gitignore)- Capacitor 8 = Swift Package Manager(SPM) 사용 (CocoaPods 아님 — Podfile 불필요)
- 웹 게이팅: iOS 는
isNativePlatform()이 true → 안내 페이지가 아닌 전체 앱 표시
사전 준비 (Mac)
- Xcode(App Store, 대용량) + iOS SDK/시뮬레이터 런타임
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer sudo xcodebuild -license accept xcodebuild -downloadPlatform iOS # 시뮬레이터 런타임(별도 온디맨드 다운로드) - Apple Developer Program($99/년) — 실기기 배포·App Store·Apple 로그인 Capability 에 필요. (시뮬레이터 UI 테스트는 불필요)
최초 셋업 (1회)
npm i @capacitor/ios
npx cap add ios # ios/ 생성
npm run build:app && npx cap sync ios
npx capacitor-assets generate --ios # 브랜드 아이콘 생성(assets/ 기준)
빌드 & 실행
npm run build:app && npx cap sync ios # 코드 변경 시마다
npx cap open ios # Xcode 열기
# 또는 CLI 로 시뮬레이터에 바로:
npx cap run ios --target <시뮬레이터-UDID>
시뮬레이터 목록: xcrun simctl list devices available | grep iPhone
실기기 실행 (Xcode)
- 데이터 지원 케이블로 아이폰 연결 → "이 컴퓨터 신뢰" (충전 전용 케이블은 인식 안 됨)
- Xcode → App 타겟 → Signing & Capabilities → Automatically manage signing → Team 선택(무료 Apple ID 도 7일 한정 가능)
- 상단 툴바 중앙 기기 선택(스킴
App옆) → 연결된 아이폰 → ▶ Run - 최초엔 아이폰이 개발자 모드를 요구 → Run 시도 후 설정 → 개인정보 보호 및 보안 → 개발자 모드 → 켬 → 재시동
- "신뢰할 수 없는 개발자" → 설정 → 일반 → VPN 및 기기 관리 → 개발자 앱 → 신뢰
필수 설정 (반영 완료)
- 번들 ID
kr.sblog.slimbudget(안드로이드와 동일 — App Store Connect 에서 그대로 사용) - Info.plist 권한 문구 (없으면 카메라/사진 접근 시 크래시):
NSCameraUsageDescription(영수증·프로필·게시판 촬영)NSPhotoLibraryUsageDescription/NSPhotoLibraryAddUsageDescription
- safe-area:
index.html의viewport-fit=cover+ CSSenv(safe-area-inset-*). ⚠️ 전역box-sizing: border-box에서 고정height를 쓰면 safe-area 패딩이 높이에 포함돼 콘텐츠가 눌린다 → 헤더는min-height+세로패딩, 하단 내비는height: calc(56px + env(safe-area-inset-bottom))로 처리(적용됨).
Apple 로그인 (Sign in with Apple)
App Store 심사 가이드라인 4.8: 제3자 소셜 로그인(구글)을 제공하면 Apple 로그인도 동등하게 제공해야 함. iOS 출시에 사실상 필수.
구현 상태(코드 완료):
- 프론트:
@capacitor-community/apple-sign-in+ LoginModal.vue Apple 버튼(iOS 전용) + appleAuth.js- ⚠️ 이 플러그인은 Capacitor 7 기준(
capacitor-swift-pm 7.x) → patch-package 로 8.x 로 패치(patches/).npm ci후postinstall이 자동 적용. @capawesome 구글 플러그인과 iOS 공존.
- ⚠️ 이 플러그인은 Capacitor 7 기준(
- 백엔드:
POST /api/auth/apple— nimbus-jose-jwt 로 Apple JWKS(공개키) 서명 검증 + iss/aud(번들ID)/exp 확인,member.apple_id로 구글과 동일하게 이메일 자동연결.app.apple-client-id(기본kr.sblog.slimbudget). ios/App/App/App.entitlements—applesignin엔틀먼트 준비됨.
작동시키려면(유료 승인 후):
- Apple Developer 포털: App ID
kr.sblog.slimbudget에 Sign in with Apple 활성화 - Xcode → Signing & Capabilities → + Capability → "Sign in with Apple" (준비된
App.entitlements연결 + 프로비저닝) - 테스트: 시뮬레이터 설정 → Apple ID 로그인 후
cap run ios→ Apple 버튼- Sign in with Apple 은 시뮬레이터에서도 작동(카메라/푸시와 달리). 단 1~2 가 갖춰져야 함.
배포 (App Store)
- 의무 테스트 기간 없음 — 안드로이드(Play)의 "테스터 12명·14일"과 달리, iOS 는 바로 심사 제출 가능. TestFlight 은 선택.
- 절차: App Store Connect 앱 생성 → 아이콘·스크린샷(6.x" iPhone 규격)·App Privacy 작성 → Xcode Archive → 업로드 → 심사(보통 1~3일)
- TestFlight(선택): 유료 승인 후 빌드 업로드 → 케이블 없이 아이폰에 무선 설치(데이터 케이블 없을 때 유용). 내부 100명 즉시 / 외부 10,000명(가벼운 베타 심사).
자주 막히는 부분
- SPM 의존성 충돌: 플러그인이 서로 다른
capacitor-swift-pm/googlesignin-ios버전을 요구하면 빌드 실패. Capacitor 8 전용 플러그인을 쓰거나(patch-package) 버전 정렬 필요. - USB 연결이 충전만 됨: 충전 전용 케이블 → 데이터 케이블로 교체. 무선 디버깅도 최초 1회 유선 페어링 필요.
- 개발자 모드 메뉴가 없음: Xcode 로 기기 설치를 한 번 시도한 뒤 설정에 항목이 생김(iOS 16+).
- Developer 등록 "보류": 개인 등록은 Apple 이 추가 본인확인을 요청할 수 있음 → Apple ID 이메일 확인 후 회신해야 진행됨(자동으로 안 풀림).
- 카메라/푸시는 시뮬레이터 제한 → 실기기 필요. Apple 로그인은 시뮬레이터 가능.
참고
- 안드로이드 빌드: ANDROID.md · 아키텍처: FRONTEND.md
- 앱 전용 백엔드 URL:
.env.capacitor의VITE_API_BASE_URL(HTTPS 필수)