비즈니스 현실6 분 읽기

스토어 설명 15개 언어가 제가 같은 날 제출한 데이터 안전 폼과 반대를 말하고 있었습니다

코드 리뷰 13건과 자체 감사를 전부 통과한 뒤였습니다. 마지막 전체 리뷰가 찾은 블로커 둘은 코드가 아니라 제가 쓴 스토어 문구였습니다.

#gotchas#app-store#distribution#reality-check
개념 도식: 스토어 설명과 데이터 안전 선언이 같은 앱에 대해 반대를 말하는 구조
글 내용을 요약한 개념 도식.

새 앱 하나를 출시 직전까지 끌고 갔습니다. 태스크별 코드 리뷰 13건 통과, 자체 출시 판정 감사 통과, 유닛 테스트 통과, 정적 분석 오류 0.

마지막으로 전체 리뷰를 한 번 돌렸습니다. 블로커가 둘 나왔는데, 둘 다 코드가 아니었습니다.

당신의 출시 체크리스트는 코드 밖을 봅니까?

첫 번째: 제가 저를 반박했습니다

스토어 설명 15개 언어에 이렇게 적혀 있었습니다.

기록은 기기를 떠나지 않습니다. 아무것도 어디로도 보내지 않습니다.

같은 세션에서 제가 채운 데이터 안전 폼에는 이렇게 선언돼 있었습니다.

구매 내역과 기기 식별자를 수집합니다.

둘 다 맞습니다. 사용자가 적은 기록은 정말 기기를 떠나지 않고, 결제 SDK는 정말 구매 내역을 받습니다. 문제는 제가 스토어 페이지에서 그 둘을 하나의 문장으로 뭉갰다는 것입니다. 앱은 매 실행마다 결제 서비스에 접속합니다.

같은 콘솔에 제출하는 두 서류가 서로를 반박하고 있었고, 저는 그걸 같은 날 썼습니다.

두 번째: 확인 없이 쓴 문장

같은 설명에 이런 줄도 있었습니다.

볼륨 키를 길게 누르면 음량만 바뀝니다.

코드를 열어보니 길게 누름 처리는 repeatCount > 0인 이벤트만 통과시킵니다. 그런데 **긴 누름의 첫 이벤트는 언제나 repeatCount == 0**입니다. 즉 첫 신호가 카운터에 들어갑니다.

에뮬레이터에서 길게 누르기 한 번에 숫자가 10에서 9로 내려갔습니다.

세 번째로, 권한을 "정확히 셋"이라고 적었는데 배포 패키지에는 다섯 개가 들어 있었습니다. 결제 권한이 포함되기 때문입니다.

왜 13건의 리뷰가 다 통과시켰나

태스크별 리뷰는 그 태스크의 산출물을 봅니다. 스토어 문구를 쓴 태스크는 문구가 그럴듯한지 봤고, 데이터 안전 폼을 채운 태스크는 폼이 정확한지 봤습니다. 각각은 옳았습니다.

둘을 한 표에 놓고 본 사람이 없었습니다.

그리고 제 자체 감사도 "코드 GO"를 냈습니다. 유닛과 정적 분석만 봤기 때문입니다. 감사 과정에서 제가 기기 데이터베이스를 더럽혀 계측 테스트가 빨간 상태였는데, 감사는 계측을 한 번도 다시 돌리지 않았습니다.

여기서 선택이 갈립니다

출시 직전에 이런 게 나오면 두 가지 반응이 있습니다. 하나는 문구를 고치고 나가는 것, 다른 하나는 왜 여기까지 왔는지 절차를 고치는 것입니다.

당신이라면 어디까지 하겠습니까?

저는 문구를 고쳐 출시했습니다. 절차 쪽은 규칙 한 줄로 남겼습니다.

스토어 문구는 코드와 대조해야 검증된 것이다. 유닛·정적 분석·번들만으로는 "코드 GO"를 말할 수 없다.

자가진단

  • 같은 심사에 제출하는 서류 둘이 서로를 반박하지 않는지 확인합니까?
  • 스토어 설명의 기능 주장을 코드에서 grep해 본 적이 있습니까?
  • 권한·수집 항목을 손으로 세고 있습니까, 아니면 빌드 산출물에서 뽑습니까?

솔직한 부분

이 앱은 결국 통과했고 심사 노트도 없이 승인됐습니다. 즉 심사가 이 모순을 잡지 않았을 것입니다. 스토어 설명과 데이터 안전 선언을 대조하는 자동 검사는 없거나, 있어도 이 정도는 안 걸립니다.

그러니 이건 "심사에 걸릴 뻔했다"는 이야기가 아닙니다. 걸리지 않고 그대로 나갔을 거라서 더 불편한 쪽입니다. 사용자에게 거짓을 말하는 문장이 15개 언어로 나갔을 겁니다.

페이월이 없는 기능을 팔던 이야기와 같은 자리입니다. 코드가 아니라 제가 쓴 문장이 제품과 어긋나 있었습니다.

당신의 스토어 설명에서 기능 주장 하나를 고르고, 그 기능의 호출부를 grep 해보세요.

관련 글