# iOS 하이브리드 앱 (Capacitor)

Vue `dist` 를 네이티브 WebView로 패키징해 iOS 앱으로 빌드합니다. 안드로이드와 **동일 코드베이스**이며, 플랫폼 분기는 `Capacitor.isNativePlatform()` / `getPlatform() === 'ios'` 로 처리합니다.

## 구성
- `capacitor.config.json` — appId `kr.sblog.slimbudget`(안드와 동일), appName `돈돼지 가계부`, webDir `dist`
- `ios/` — 네이티브 프로젝트(커밋됨, 빌드 산출물 `ios/App/build`·`Pods` 는 .gitignore)
- **Capacitor 8 = Swift Package Manager(SPM)** 사용 (CocoaPods 아님 — Podfile 불필요)
- 웹 게이팅: iOS 는 `isNativePlatform()` 이 true → 안내 페이지가 아닌 전체 앱 표시

## 사전 준비 (Mac)
- **Xcode**(App Store, 대용량) + iOS SDK/시뮬레이터 런타임
  ```bash
  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회)
```bash
npm i @capacitor/ios
npx cap add ios                 # ios/ 생성
npm run build:app && npx cap sync ios
npx capacitor-assets generate --ios   # 브랜드 아이콘 생성(assets/ 기준)
```

## 빌드 & 실행
```bash
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)
1. **데이터 지원 케이블**로 아이폰 연결 → "이 컴퓨터 신뢰" (충전 전용 케이블은 인식 안 됨)
2. Xcode → **App 타겟 → Signing & Capabilities → Automatically manage signing → Team 선택**(무료 Apple ID 도 7일 한정 가능)
3. 상단 툴바 중앙 **기기 선택**(스킴 `App` 옆) → 연결된 아이폰 → **▶ Run**
4. 최초엔 아이폰이 **개발자 모드**를 요구 → Run 시도 후 **설정 → 개인정보 보호 및 보안 → 개발자 모드 → 켬 → 재시동**
5. "신뢰할 수 없는 개발자" → **설정 → 일반 → VPN 및 기기 관리 → 개발자 앱 → 신뢰**

## 필수 설정 (반영 완료)
- **번들 ID** `kr.sblog.slimbudget` (안드로이드와 동일 — App Store Connect 에서 그대로 사용)
- **Info.plist 권한 문구** (없으면 카메라/사진 접근 시 크래시):
  - `NSCameraUsageDescription`(영수증·프로필·게시판 촬영)
  - `NSPhotoLibraryUsageDescription` / `NSPhotoLibraryAddUsageDescription`
- **safe-area**: `index.html` 의 `viewport-fit=cover` + CSS `env(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](../src/components/LoginModal.vue) Apple 버튼(iOS 전용) + [appleAuth.js](../src/native/appleAuth.js)
  - ⚠️ 이 플러그인은 Capacitor 7 기준(`capacitor-swift-pm 7.x`) → **patch-package** 로 8.x 로 패치(`patches/`). `npm ci` 후 `postinstall` 이 자동 적용. @capawesome 구글 플러그인과 iOS 공존.
- 백엔드: `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` 엔틀먼트 준비됨.

**작동시키려면(유료 승인 후):**
1. Apple Developer 포털: App ID `kr.sblog.slimbudget` 에 **Sign in with Apple 활성화**
2. Xcode → Signing & Capabilities → **+ Capability → "Sign in with Apple"** (준비된 `App.entitlements` 연결 + 프로비저닝)
3. 테스트: 시뮬레이터 **설정 → 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](ANDROID.md) · 아키텍처: [FRONTEND.md](FRONTEND.md)
- 앱 전용 백엔드 URL: `.env.capacitor` 의 `VITE_API_BASE_URL`(HTTPS 필수)
