AI 사용기
AI 활용기: 반려 스크린샷을 고쳐 올렸는데 16장이 됐다
App Store Connect 스크린샷 교체가 덮어쓰기가 아니라 추가라는 걸 반려 이후에야 알게 된 사례와, 같은 함정을 겪은 fastlane 사용자들의 실제 이슈를 같이 정리했다.
스토어 자동화 스크립트로 스크린샷을 갱신하는 사람에게, '새로 올렸다'와 '옛 것을 지웠다'가 왜 다른 확인인지 구체적 사례로 보여준다.
반려 사유가 된 스크린샷을 고쳐 10장을 새로 올렸더니 심사 대상이 16장이 됐다 — App Store Connect의 스크린샷 업로드는 기본이 추가이지 교체가 아니다. fastlane deliver도 같은 구조라 overwrite_screenshots 옵션을 기본값 false로 두면 똑같이 쌓이고, 옵션을 켜도 삭제 단계 자체가 실패하는 사례가 실제 이슈로 보고돼 있다.
스크린샷을 다시 올리기 전에 항상 기존 컷을 먼저 비우거나 삭제를 확인하고, 그 확인이 도구가 자동으로 해줄 거라 가정하지 않는다.
먼저 답하면
스토어 스크린샷을 새로 올린 개수와, 심사에 올라가는 개수는 다를 수 있다. App Store Connect는 스크린샷 업로드를 교체가 아니라 추가로 처리하기 때문에, 옛 컷을 먼저 지우지 않으면 새 컷은 옛 컷 위에 그냥 쌓인다.
반려된 컷을 고쳤는데 6장이 늘었다
앱 하나가 스크린샷 문제로 반려됐다. 반려 사유가 된 컷들을 새로 찍어 10장을 다시 올렸는데, App Store Connect에서 확인해보니 심사 대상이 16장이었다. 새로 올린 10장은 맞게 들어갔지만, 반려 원인이었던 옛 컷들이 그대로 남아 새 컷과 함께 심사에 갔던 것이다.
원인은 단순했다. ASC의 스크린샷 업로드는 “이 슬롯을 이 이미지로 바꿔라”가 아니라 “이 이미지를 추가해라”에 가깝게 동작한다. 문장을 고치고 화면을 다시 캡처해도, 지우는 단계를 따로 거치지 않으면 옛 화면은 여전히 심사 목록에 있다. 이 자동화 파이프라인에서는 이후 asc_shots.py에 clear 명령을 넣어, 항상 비우고 나서 다시 올리는 순서로 고쳤다.
같은 종류의 함정이 로컬에도 있었다. 스크린샷을 언어별 폴더(screenshots/<locale>/)에 저장하도록 구조를 바꾼 뒤에도, 그 이전 방식으로 만든 앱은 컷이 폴더 없이 평면으로 남아 있었다. 두 구조가 한 프로젝트에 공존하면 검수 스크립트는 옛 평면 경로를 먼저 읽는다 — 문장을 몇 번 고쳐도 실제로 심사에 가는 이미지는 그대로인 상태가 된다. 이 경우도 파일이 잘못 갱신됐다기보다, “새로 만든 파일”과 “실제로 참조되는 파일”이 다른 경로에 있다는 걸 놓친 문제였다.
fastlane 사용자들도 같은 자리에서 걸렸다
이 문제는 Apple 자동화 커뮤니티에서 이미 알려진 함정이다. fastlane의 deliver/upload_to_app_store 액션 공식 문서를 보면 overwrite_screenshots 옵션이 명시적으로 존재한다. 설명은 “새 스크린샷을 올리기 전에 기존에 올라간 모든 스크린샷을 지운다”이고, 기본값은 false다. 즉 아무 옵션도 안 주면 fastlane도 기본은 추가이지 교체가 아니라는 뜻이다.
옵션을 켜도 문제가 완전히 사라지는 건 아니다. fastlane GitHub 이슈 #19935에서는 Xcode 에셋에 새 스크린샷을 추가하고 overwrite_screenshots: true로 upload_to_app_store를 돌렸더니 업로드 마지막 단계에서 실패했고, App Store Connect에는 옛 스크린샷과 새 스크린샷이 “6장 전부” 같이 남았다는 실사용 보고가 있다. 같은 저장소의 토론 #19605에서는 overwrite_screenshots: true와 force: true를 함께 켰는데도 기존 스크린샷 삭제 단계 자체가 반복 실패하며 “삭제되지 않은 스크린샷 수: 12”라는 로그를 남긴 사례가 보고돼 있다. 옵션을 켜서 “지워지길 기대”하는 것과 “실제로 지워졌는지 확인”하는 것은 다른 확인이라는 뜻이다.
도구를 믿는 것과 결과를 확인하는 것은 다른 확인이다
세 사례의 공통점은 “업로드에 성공했다”는 신호와 “옛 것이 지워졌다”는 사실이 서로 독립이라는 점이다. API든 fastlane이든 업로드 요청 자체는 정상 응답을 돌려줄 수 있고, 그 응답만 보면 작업이 끝난 것처럼 보인다. 실제로 무엇이 심사 목록에 남아 있는지는 별도로 세어봐야 드러난다.
이후로는 스크린샷을 다시 올리는 작업을 “새 컷 업로드”가 아니라 “비우기 → 업로드 → 개수 확인”의 세 단계로 고정했다. 옵션 하나를 켜는 것보다, 작업이 끝난 뒤 실제로 몇 장이 남아 있는지 세어보는 습관이 더 확실했다.