Skip to content

App Store 제출 준비물 — 심사 노트·App Privacy 라벨·연령 등급·스크린샷 (이슈 #665 Phase 5·6, 2026-09-02)

앱스토어 심사 트랙(#665)의 마지막 두 Phase. 코드는 이미 랜딩됐고(Phase 1·2·3·7·8), 이 문서는 오너가 Mac에서 빌드·업로드하고 App Store Connect에 입력할 때 그대로 옮겨 적는 값이다. 규정 근거는 App Store Review Guidelines 2026 기준.

0. 제출 전 상태 확인 (코드 쪽, 자동 증거)

항목상태근거
앱 내 계정 삭제 (5.1.1(v))내 정보 → 계정 삭제 2단 확인 → 서버 삭제·Apple 토큰 해제·카카오 연결 해제 (#663)
UGC 신고·차단 — 피드 (1.2)게시 전 금칙어·신고·차단·차단 관리·문의 이메일·약관 v4 무관용 조항 (#670)
UGC 신고·차단 — 그룹 (1.2)라운지 채팅·보드 댓글·공지 신고·차단, 초대 차단, 정지 게이트, 그룹명·공지 금칙어 (#922, PR #1137)
Sign in with Apple (4.8)네이티브 시트, 버튼 3개 동등 크기
privacy manifest·수출 규정 키ios/App/App/PrivacyInfo.xcprivacy · ITSAppUsesNonExemptEncryption = false (PR #1136)
서버 연결 실패 시 안내 화면public/offline.html (Capacitor server.errorPath)
데이터 내보내기 앱 동작✅ 코드shareFile 브리지 → iOS 공유 창. Swift 컴파일·실기기 동작은 Mac 빌드에서 확인
iPad 제외·세로 고정TARGETED_DEVICE_FAMILY = 1, Portrait만
카메라·사진 권한 문구 (2.1 크래시 방지)프로필 사진 변경 선택기의 "사진 찍기"용 NSCameraUsageDescription + NSPhotoLibraryUsageDescription (09-03 재점검에서 발견·수리)

Production 반영 전제: 위 PR #1136·#1137이 실린 릴리스(main → production PR)가 머지된 뒤 빌드한다. 원격 웹 로드 셸이라 앱 바이너리는 Production 웹을 그대로 보여준다 — 릴리스 전에 심사에 넣으면 심사관은 staging이 아니라 옛 Production을 본다.

1. 심사 노트 (App Review Information → Notes)

심사관은 영어를 읽으므로 영문으로 넣는다. 아래 그대로 붙여 넣고 [ ]만 채운다.

Barbelic is a Korean-language workout logging app (weightlifting, calisthenics, cardio).

SIGN-IN
- No demo account is required. Please create a new account with "Apple로 계속하기" (Sign in with Apple) on the first screen. Kakao and Google sign-in are also offered; Sign in with Apple is fully equivalent.
- After sign-in the onboarding asks for: terms consent → nickname & handle → body weight → main lifts → 1RM (optional). All steps can be completed in under a minute; every field has a default.
- The UI is in Korean. Tab bar (left to right): 홈 Home · 피드 Feed · 그룹 Groups · 세션 Sessions/Calendar · 내 정보 Profile.

ACCOUNT DELETION (Guideline 5.1.1(v))
- 내 정보 (Profile) → scroll to bottom → 계정 삭제 (Delete account) → confirm → type "계정 삭제" → delete. The server deletes all user data immediately and revokes the Sign in with Apple token. A web path also exists: https://app.barbelic.com/account/delete.html

USER-GENERATED CONTENT (Guideline 1.2)
- Feed posts, comments, group chat, group notices and group board comments can be reported (신고) and their authors blocked (차단) from the "⋯" / "신고" control on any other user's content. Reported content disappears immediately for the reporter; blocked users disappear from every surface. Blocked users are managed in 내 정보 → 차단한 사용자.
- Profanity is filtered before posting. Terms of Service section 8 states the zero-tolerance policy; the developer contact e-mail is shown in 내 정보 → 문의 (support@barbelic.com). Reports are reviewed within 24 hours.

NATIVE FUNCTIONALITY (why this is not a web wrapper — Guideline 4.2)
The app shell loads the web application from https://app.barbelic.com and adds native integrations that the website cannot provide:
- Sign in with Apple through the system sheet (ASAuthorizationController), not a web page.
- Session persistence in the iOS Keychain with PKCE verifier storage; login survives app restarts.
- Saving a workout summary image to the Photos app (NSPhotoLibraryAddUsageDescription).
- Exporting personal data through the iOS share sheet.
- Keeping the screen awake during an active workout (idle timer).
- Native launch screen ownership and swipe-back navigation.
- Apple re-authentication during account deletion for token revocation.
- An offline page bundled in the app when the server cannot be reached.

HEALTH DATA
- The app stores body weight, optional body-composition values the user imports themselves (InBody), and workout records. It does not read or write HealthKit and does not share health data with third parties.

CONTACT
- [owner name], [phone with country code], support@barbelic.com

연락처 전제(2026-09-15, #1625 Phase 1 실측): barbelic.com에는 아직 메일 수신(MX) 설정이 없어 support@barbelic.com으로 보낸 메일은 반송된다. 제출 전에 오너가 메일 서비스를 연결하고 다른 주소에서 테스트 메일 수신을 확인해야 한다. 그 전에는 위 CONTACT 줄에 수신되는 주소를 적는다.

2. App Privacy (App Store Connect → App Privacy)

"Do you collect data from this app?" → Yes. 트래킹(Tracking) → No. 모든 항목은 "Linked to the user", 용도 "App Functionality". PrivacyInfo.xcprivacy의 목록과 같아야 한다 — 하나를 바꾸면 둘 다 바꾼다.

데이터 유형 (ASC 이름)세부수집 이유 (앱에서 무엇)
Contact Info → Email Address소셜 로그인 계정 이메일계정 식별·문의 답변
Contact Info → Name소셜 프로필 표시 이름프로필 표시
Health & Fitness → Fitness운동 기록·칼로리 추정앱 기능
Health & Fitness → Health체중, 사용자가 직접 가져오는 InBody 체성분볼륨·기록 계산
User Content → Photos or Videos프로필 사진프로필 표시
User Content → Other User Content댓글·채팅·보드·자유 기록소셜 기능
Identifiers → User IDSupabase user id계정 연결
Diagnostics → Crash Data앱 오류 이벤트(client_error_events, user id 연결, 90일 보관)장애 진단
Diagnostics → Performance Data같은 이벤트의 응답 시간·상태장애 진단

수집하지 않음: 위치, 연락처, 검색 기록, 구매, 광고 데이터, 기기 ID(광고용).

3. 연령 등급 (Age Rating 설문)

질문
Unrestricted Web AccessNo (앱 안에 브라우저 없음 — 웹뷰는 자사 사이트만)
User Generated Content / Frequent or IntenseYes / Infrequent — 신고·차단·필터링 있음
Gambling, ContestsNo
Medical/Treatment InformationNo (칼로리는 추정치 표기, 의료 정보 아님)
그 외 폭력·성적·약물None

결과 등급은 4+ 또는 12+(UGC 답에 따라)로 나온다. 약관은 만 14세 미만 이용 불가 — 등급과 별개로 스토어 설명에 적지 않아도 된다.

4. 스크린샷·메타데이터

  • 기기: 6.7형(iPhone 15 Pro Max 등) 필수, 6.1형 권장. iPad는 타깃 제외라 불필요.
  • 계정: 오너 본인 계정(기록이 채워진 상태)으로 촬영. 데모 계정은 없다.
  • 권장 5장: ① 홈(오늘 요약·시작 바) ② 세션 상세(세트 기록) ③ 리포트(잔디·성장) ④ 피드(포스트·댓글) ⑤ 그룹 화이트보드.
  • 앱 이름: Barbelic(첫 글자 B 대문자, 브랜드 정본). 부제·키워드는 한국어. 지원 URL: https://app.barbelic.com/legal/service-info.html. 개인정보 처리방침 URL: https://app.barbelic.com/legal/privacy-v1.html. 이용약관 URL: https://app.barbelic.com/legal/terms-v1.html. (출시판 v1, 2026-09-15 #1640 — 앱 v0.19.4부터 이 파일을 앱이 직접 제공한다. 2026-09-15 도메인 분리 뒤 www.barbelic.com은 랜딩이며 같은 경로는 app 주소로 308 이동한다.)
  • 카테고리: Health & Fitness.

5. Mac에서 하는 순서 (오너 손작업)

  1. 최신 main(릴리스 반영 후) → npm ci && npm run build && npm run ios:sync && npm run ios:open
  2. Xcode: Team 선택, App 타깃 → General → Version 1.0·Build 번호 올리기(제출마다 +1). Signing & Capabilities에 Sign in with Apple 있음 확인.
  3. Product → Archive → Distribute → App Store Connect → Upload. privacy manifest가 있으므로 ITMS-91053 경고 없이 처리돼야 한다. 암호화 질문은 plist 키로 생략된다.
  4. App Store Connect: 빌드 선택 → 1절 심사 노트 → 2절 App Privacy → 3절 연령 등급 → 4절 스크린샷·메타데이터 → 제출.
  5. 실기기(TestFlight)에서 한 번 열어 볼 것: 로그인 → 홈 → 기내 모드로 재실행 시 오프라인 안내 화면 → 내 정보 → 데이터 내보내기 공유 창. 이 두 가지(오프라인 화면·공유 창)는 Windows에서 검증할 수 없었던 Swift 변경분이다.

6. 반려 시 대응

반려 사유대응
4.2 "web wrapper"1절 NATIVE FUNCTIONALITY 목록을 그대로 답신. 필요하면 Photos 저장·Keychain·SiwA 시트 동작 영상 첨부
2.1 로그인 불가심사관이 SiwA 새 가입을 안 했을 가능성 — 1절 SIGN-IN 재안내. 그래도 막히면 그때 데모 계정(이메일 로그인 경로 신설) 검토
5.1.1 라벨 불일치2절 표와 PrivacyInfo.xcprivacy를 대조해 같은 값으로
1.2 UGC1절 USER-GENERATED CONTENT 경로를 화면 이름 그대로 답신

심사용 이메일 로그인과 새 계정 시드 — 2026-09-11 (#1568)

2026-09-11 사용자 결정으로 새 심사 전용 계정과 이메일·비밀번호 진입을 준비한다. 위의 2026-09-02 "데모 계정 없음"은 당시 제출 방침이며 이번 후보에 대해서는 이 절이 우선한다. 계정 생성·배포 성공을 의미하지 않으며 실제 적용 결과는 작업 이슈 #1568에 기록한다.

일반 로그인 화면에 이메일/비밀번호 버튼이나 폼을 노출하지 않는다. 모바일·데스크톱·로그인 오류 대체 화면에서 Barbelic 로고를 5회 누르면 심사용 로그인 창이 열린다. 키보드는 로고에 초점을 둔 뒤 Enter/Space 5회로 같은 창을 연다. App Review Notes에 이 경로와 실제 발급된 계정 정보를 제공한다. 숨긴 기능을 심사관에게 미고지하는 용도가 아니다.

인증은 Supabase의 정상 이메일·비밀번호 인증이다. 임시 비영속 Auth client로 인증한 뒤 서버 관리 app_metadata.barbelic_review_account === true 계정만 기존 앱 client에 세션을 전달한다. 일반 계정의 user_metadata로 이 조건을 충족할 수 없다. 보기모드·관리자 대행·자동 로그인·새 권한을 만들지 않는다. 비밀번호는 폼 메모리에서만 다루고 실패/닫힘 후 비우며 URL·telemetry·fixture·Git에 기록하지 않는다.

시드는 앱 scripts/review-account/에서 실행한다. 인물·종목·운동·그룹·피드·PR·즐겨찾기 원본은 화면 fixture와 공유한다. 기본 실행은 계획 출력이고 실제 쓰기에는 --apply와 명시 target을 요구한다. 새 합성 계정·그룹만 namespace별 관리하며 기존 사용자 계정을 자동 채택하거나 원본 운동을 삭제/덮어쓰지 않는다. 동일 manifest 재실행은 이전 완료 작업을 재사용하고 응답이 불확실하면 읽기로 조정한다. 실제 RPC 검증과 재실행 증거가 없으면 완료로 보지 않는다.

환경 URL·publishable/anon key·service role key·심사 계정 이메일은 실행 환경 변수로 받는다. 비밀번호와 계정 매핑은 Git 밖의 private manifest/credentials에만 쓴다. 새 실제 심사 계정의 소셜 연결 상태는 미연결이며 프리뷰의 연결 표시 변형과 구분한다. 운동·PR 날짜는 고정한 기준일의 상대 날짜를 실제 DB 날짜로 저장한다. 댓글·공지 생성시각은 서버 now()이며 시드 검증 결과가 실제 시각을 기록한다. 시간이 지난 심사 계정의 날짜를 자동 덮어쓰는 유지 작업은 이번 범위가 아니다.

계정 생성과 숨김 로그인 코드 배포는 별도다. 로컬 검증 성공·로컬 계정 생성은 Production 계정/배포 성공이 아니며, 원격 CI는 사용자가 명시적으로 지시한 범위에서만 실행한다.

실행 예시는 앱 checkout 기준이다. 명령행에는 비밀번호나 service role key를 직접 넣지 않는다.

sh
npm run review:account -- --target local --namespace app-review-v1 --today 2026-09-11
npm run review:account -- --target local --namespace app-review-v1 --apply
npm run review:account -- --target local --namespace app-review-v1 --verify

환경 변수는 REVIEW_SUPABASE_URL, REVIEW_SUPABASE_ANON_KEY, REVIEW_SUPABASE_SERVICE_ROLE_KEY, REVIEW_ACCOUNT_EMAIL이다. REVIEW_ACCOUNT_PASSWORD를 생략하면 충분한 길이의 난수 비밀번호를 생성한다. 원격 target에는 REVIEW_EXPECTED_PROJECT_REF로 프로젝트도 대조한다. --state-dir은 Git 밖의 manifest 저장 위치이며 기존 manifest가 있으면 최초 기준일을 유지한다. 위 날짜는 문서 예제일 뿐 실제 실행 기준일은 실행 시 지정한다.