카메라 기능이 들어간 Cordova iOS 앱은 개발 빌드에서는 잘 되다가, 릴리즈(Archive/App Store 배포) 단계에서 서명/권한/플러그인 설정 하나 때문에 심사 리젝 또는 크래시로 막히는 경우가 많습니다. 아래는 “서명/배포 실수 방지” 관점으로 정리한 플러그인/권한 체크리스트입니다.
릴리즈 직전에 한 번만 훑어도 실수 확률이 확 줄어듭니다.
1) 카메라 플러그인 구성(무엇을 쓰는지)부터 확정하기
가장 먼저 “카메라를 어떻게 쓸 것인지”를 확정해야 체크 포인트가 줄어듭니다. Cordova iOS에서 흔한 선택지는 아래 두 가지입니다.
- cordova-plugin-camera: 촬영/앨범 선택을 Cordova API로 처리. 릴리즈 시 권한 문구(Info.plist) 누락이 가장 흔한 실수입니다.
- cordova-plugin-ionic-webview + getUserMedia 조합: 웹뷰에서 직접 카메라 스트림을 쓰는 패턴(특히 스캔/실시간 프리뷰). iOS에서는 WKWebView 권한/https/ATS/미디어 재생 정책까지 함께 봐야 합니다.
이미 프로젝트에 카메라 관련 플러그인이 여러 개 섞여 있다면(예: camera + file + photo-library + crop) 릴리즈 전에는 “실제로 쓰는 것만 남기고 정리”하는 쪽이 안전합니다. 안 쓰는 플러그인이 Info.plist 항목을 추가하거나 충돌을 만들기도 합니다.
2) Info.plist 권한 문구: 심사 리젝 1순위(문구 누락/부정확)
App Store 심사에서 가장 흔한 리젝은 “권한 사용 목적이 불명확”하거나 “필수 키가 없다”는 유형입니다. 카메라 관련으로는 아래를 최우선으로 확인하세요.
- NSCameraUsageDescription: 카메라 사용 목적을 사용자 관점으로 1~2문장으로 명확히 작성
- NSPhotoLibraryUsageDescription: 촬영 후 저장/앨범 선택이 있다면 필요
- NSPhotoLibraryAddUsageDescription: 사진 저장만 하는 경우(읽기는 안 함)에도 요구될 수 있어 동작에 맞게 명시
실무 팁:
- 문구에 “광고/추적”처럼 오해될 단어를 섞지 않습니다. 심사 대응이 어려워질 수 있습니다.
- 앱의 실제 동작과 문구가 다르면 리젝 사유가 됩니다(예: “프로필 사진 촬영”이라 써놓고 실제로는 문서 스캔/업로드까지 하는 경우).
- 여러 플러그인이 같은 키를 덮어쓰는 경우가 있어, 최종 산출물의 Info.plist를 Xcode에서 직접 확인합니다.
확인 위치: Xcode에서 iOS 프로젝트(플랫폼) 열고 Target의 Info 탭 또는 빌드 산출물의 Info.plist를 확인하세요.
3) 릴리즈 서명/Provisioning: 카메라 자체보다 여기서 더 많이 막힙니다
카메라 기능과 직접 관련 없어 보여도, 릴리즈에서 서명이 꼬이면 “권한 프롬프트가 안 뜸/앱이 즉시 종료/특정 기기에서만 크래시” 같은 형태로 나타나기도 합니다. 다음을 고정 루틴으로 두면 안전합니다.
- Bundle Identifier가 Apple Developer에 등록된 App ID와 정확히 일치하는지
- Release용 Provisioning Profile이 해당 App ID에 매핑되어 있는지(팀/계정 혼동 주의)
- Signing Certificate가 만료되지 않았는지(특히 장기 프로젝트)
- Xcode 자동 서명(Automatically manage signing)을 쓸지/수동으로 고정할지 팀 룰을 정해 혼용하지 않기
또 하나: Debug로는 잘 되는데 Archive에서만 실패한다면, 대부분 “릴리즈 구성에서만 포함되는 설정/스크립트/Entitlements/빌드 단계”가 원인입니다. 카메라 건이라도 서명 상태부터 먼저 단단히 고정하는 게 시간을 절약합니다.
4) WKWebView/권한 흐름 점검: getUserMedia 계열이면 특히 중요
웹뷰에서 카메라 스트림(getUserMedia)을 쓰는 패턴이라면, 플러그인 권한 외에 “웹뷰 정책”이 함께 맞아야 릴리즈에서도 동일하게 동작합니다.
- HTTPS: 카메라 접근은 보안 컨텍스트가 사실상 전제입니다. 개발 중 http로 테스트했다면 릴리즈에서는 동일 환경이 아닙니다.
- ATS(App Transport Security): 임시로 예외를 열어둔 상태라면 릴리즈 전에 최소화/정리
- 카메라 권한 요청 타이밍: 앱 시작 직후 무조건 요청보다, 사용자가 카메라 기능을 눌렀을 때 요청하는 흐름이 심사/UX 모두 안정적
테스트 포인트는 “권한 팝업이 뜨는지”만이 아니라, 거부했을 때(deny) 앱이 정상 안내를 하는지까지입니다. 심사에서 실제로 거부 시나리오를 보는 경우가 있습니다.
5) 릴리즈 전 최종 점검 체크리스트(플러그인/권한/배포 한 장 요약)
- 플러그인: 실제 사용 플러그인만 남겼는지(중복/미사용 제거)
- Info.plist: NSCameraUsageDescription 필수, 사진 저장/선택 동작에 맞는 PhotoLibrary 키가 모두 있는지
- 문구 품질: 기능과 정확히 일치하는 사용자 관점 설명인지(모호한 문장/오해 단어 제거)
- 서명: Bundle ID, Team, Provisioning Profile, Certificate 만료/일치 여부 확인
- Archive 테스트: Debug가 아니라 Archive로 설치(TestFlight 또는 Ad Hoc)해 실제 기기에서 권한/촬영/저장까지 end-to-end 확인
- 거부 시나리오: 카메라 권한 거부 후 재시도 안내(설정 이동 안내 포함)가 준비되어 있는지
6) 흔한 실수 패턴과 빠른 진단 힌트
- 심사 리젝: “권한 사용 목적이 불명확” → Info.plist 문구를 기능 단위로 구체화(예: “문서 스캔을 위해 카메라가 필요합니다”). 실제 앱 화면/메타데이터 설명과도 일관성 유지
- TestFlight에서만 카메라 화면이 검게 나옴 → Archive 빌드로 설치했을 때 권한 팝업이 떴는지부터 확인. getUserMedia라면 HTTPS/ATS/웹뷰 설정 차이도 점검
- 특정 기기/특정 iOS 버전만 실패 → 플러그인 버전 고정 여부 확인(팀원이 plugin add/upgrade로 버전이 달라지는 경우가 많음). 릴리즈 직전에는 lock(고정)하고 재현 환경을 맞추는 게 중요
- 카메라 촬영 후 저장이 안 됨 → 사진 라이브러리 관련 키가 동작과 맞게 들어갔는지, 저장 권한 흐름을 실제로 탔는지 확인
마무리
Cordova iOS 카메라 이슈는 “카메라 코드”보다도 릴리즈 단계의 서명/권한 문구/플러그인 정리에서 더 자주 터집니다. 특히 Archive 기반으로 한 번 end-to-end 테스트하는 습관이 가장 큰 사고 방지책입니다.
위 체크리스트대로 정리해도 문제가 남는다면, 실제 사용 플러그인 목록과 최종 Info.plist의 권한 키/문구, 그리고 Archive 빌드 로그를 함께 묶어서 원인 범위를 좁혀보는 게 빠릅니다.