모바일 앱 프로젝트가 웹과 다른 지점 — 심사·배포·버전 관리

웹 서비스를 여러 번 만들어본 팀이 앱 프로젝트를 처음 맡으면 일정이 밀리는 경우가 많습니다. 화면 수도 비슷하고 기능도 비슷한데 그렇습니다.

원인은 개발 난이도가 아니라 배포 구조의 차이입니다. 웹은 고치면 그 순간 모든 사용자에게 반영됩니다. 앱은 그렇지 않습니다. 심사를 거쳐야 하고, 사용자가 업데이트를 받아야 하고, 받지 않은 사람은 예전 버전을 계속 씁니다.

이 차이 하나가 일정, 설계, 운영 전반에 영향을 줍니다. 이 글은 앱 프로젝트를 준비하실 때 웹과 다르게 잡아야 하는 것들을 정리한 내용입니다.


1. 배포가 즉시 이루어지지 않습니다

가장 큰 차이이고, 나머지 차이의 대부분이 여기서 파생됩니다.

심사라는 단계가 생깁니다

앱 스토어에 올리려면 심사를 통과해야 합니다. 이 단계는 개발 일정과 별개로 존재합니다.

일정에 반영할 때 고려할 점입니다.

  • 심사에 걸리는 시간은 고정되어 있지 않습니다
  • 반려될 수 있습니다. 수정하고 다시 제출하면 처음부터 다시 기다립니다
  • 제출 정보가 불완전하면 더 오래 걸립니다. 심사용 계정이나 설정 방법이 빠진 경우가 대표적입니다
  • 스토어마다 기준과 소요가 다릅니다

두 스토어 모두 심사 기간을 보장하지 않습니다. 공식 문서에 적힌 것은 통계와 주의 문구입니다(2026년 10월 13일 확인).

스토어 공식 문서의 표현 일정에 반영하는 방법
App Store 통상 제출의 50% 이상을 24시간 안에, 90%를 48시간 안에 심사. 제출 내용이 불완전하면 지연되거나 통과하지 못할 수 있음 (App Review) 평균값으로 일정을 잡지 않고, 반려 1회와 재심사를 포함한 기간을 확보
Google Play 일부 개발자 계정은 심사에 최대 7일, 예외적으로 그 이상이 걸릴 수 있음 (Play Console 고객센터: 앱 게시) 신규 계정의 첫 출시는 1주 이상을 별도로 확보

App Store 심사 지침은 같은 지침 위반으로 반복 반려되면 심사가 더 오래 걸린다고 밝히고 있습니다(App Review Guidelines, 2026년 6월 8일 개정본). 반려 사유를 고치지 않고 설명만 바꿔 다시 내는 방식은 일정을 더 밀리게 합니다.

시연 일정을 심사 완료일에 맞춰 잡으면 위험합니다. 반려가 한 번만 나도 일정이 흔들립니다. 내부 배포 수단으로 먼저 확인하고, 스토어 배포는 여유를 두는 편이 안전합니다.

내부 배포 수단을 먼저 엽니다

시연과 검수는 스토어 공개 심사와 분리된 경로로 진행합니다. 두 스토어가 제공하는 테스트 배포의 조건은 다음과 같습니다(2026년 10월 13일 확인).

구분 대상과 한도 심사 유의점
TestFlight 내부 테스터 App Store Connect 사용자 최대 100명 베타 빌드 심사는 외부 테스터를 초대할 때 적용 발주사 담당자를 App Store Connect 사용자로 등록해야 함
TestFlight 외부 테스터 최대 10,000명 그룹에 처음 추가한 빌드는 심사를 거침. 이후 빌드는 전체 심사가 생략될 수 있음 빌드는 최대 90일간 테스트 가능
Google Play 내부 테스트 앱당 최대 100명 표준 정책·보안 심사 대상이 아닐 수 있음 새 빌드가 수 분 안에 테스터에게 전달됨
Google Play 비공개 테스트 이메일 목록 단위로 관리 첫 게시 후 테스트 링크가 열리기까지 수 시간이 걸릴 수 있음 신규 개인 계정은 이 단계가 프로덕션 출시의 선행 조건 (6장 참고)

(TestFlight overview, Play Console 고객센터: 테스트 설정)

TestFlight 빌드의 90일 만료는 장기 검수에서 자주 걸립니다. 검수 기간이 길어지면 만료 전에 새 빌드를 올리는 일을 일정표에 넣어 둡니다.

반려 사유는 대체로 정해져 있습니다

미리 알고 있으면 피할 수 있는 것들입니다.

유형 내용
심사용 계정 로그인이 필요한 앱인데 심사자가 들어갈 계정을 제공하지 않음
기능 미완성 준비 중 화면, 동작하지 않는 버튼
권한 설명 부족 카메라·위치·알림 권한을 요청하는 이유가 불명확
개인정보 처리방침 링크 누락 또는 실제 수집 항목과 불일치
결제 정책 디지털 재화를 외부 결제로 처리
콘텐츠 연령 등급과 실제 내용 불일치
계정 삭제 가입은 앱에서 되는데 탈퇴는 고객센터로만 가능
링크·화면 동작하지 않는 링크, 실제 화면과 다른 스크린샷

이 중 심사용 계정 누락과 권한 설명 부족이 특히 흔합니다. 제출 전 점검 목록에 넣어두면 한 번의 반려를 줄일 수 있습니다. Apple 은 해결되지 않은 심사 이슈의 40% 이상이 지침 2.1(앱 완성도)과 관련된다고 밝히고 있습니다(App Review, 2026년 10월 13일 확인). 준비 중 화면, 동작하지 않는 링크, 빠진 심사용 계정이 모두 이 항목에 들어갑니다.

결제 항목은 범위를 정확히 봐야 합니다. 두 스토어의 인앱결제 의무는 앱 안에서 쓰는 디지털 콘텐츠와 기능에 적용됩니다. 실물 상품과 오프라인 서비스 결제는 대상이 아니며, Google Play 는 이런 결제에 Play 결제 시스템을 쓰지 못하게 정해 두었습니다(Google Play 결제 정책). 구독, 이용권, 포인트 충전처럼 디지털 재화에 해당하는 기능이 있다면 설계 단계에서 인앱결제 적용 여부를 먼저 판정합니다. App Store 가 한국에서 허용하는 대체 결제 권한은 한국 전용 앱 바이너리를 따로 제출해야 하고 Apple 인앱결제와 한 앱에서 함께 쓸 수 없는 등의 조건이 붙으므로(Apple: 한국 내 외부 결제 권한), 적용을 검토한다면 프로젝트 초기에 조건을 확인해야 합니다.

반려되었을 때의 대응 절차

반려 통지를 받은 날 누가 무엇을 할지 정해 두면 재제출까지의 시간이 줄어듭니다.

  1. 사유를 분류합니다. 통지에 적힌 지침 번호를 확인하고, 심사 정보만 고치면 되는지(계정, 설명, 스크린샷) 앱을 다시 빌드해야 하는지 나눕니다. 앞의 경우는 당일 재제출이 가능합니다.
  2. 재현합니다. 심사자가 본 화면을 같은 조건(심사용 계정, 최신 OS, 권한 거부 상태)으로 따라가 봅니다. 심사용 계정이 만료되었거나 심사 중 서버가 점검 상태였던 경우가 적지 않습니다.
  3. 질문이 있으면 심사팀에 회신합니다. App Store 는 App Store Connect 안에서 심사팀과 직접 연락하도록 안내합니다. 기능이 오해받은 경우에는 재현 절차와 화면 녹화를 함께 보냅니다.
  4. 고쳐서 다시 제출합니다. 심사 메모에 무엇을 어떻게 고쳤는지 지침 번호와 함께 적습니다. 새 기능과 변경 사항을 일반적인 문구로만 적은 심사 메모는 그 자체가 반려 사유입니다(지침 2.3.1).
  5. 판단이 다르면 이의를 제기합니다. App Store 는 반려 건당 한 번의 이의 제기를 받으며, 추가 정보 요청에 먼저 답한 뒤 제출하도록 정해 두었습니다.
  6. 기록을 남깁니다. 반려 사유, 조치, 재제출일을 문서로 남깁니다. 다음 버전에서 같은 사유가 반복되는 것을 막고, 일정 지연의 근거 자료가 됩니다.

운영 중 장애로 급한 수정이 필요할 때 쓸 수 있는 경로가 App Store 에 두 가지 있습니다. 하나는 신속 심사 요청입니다. 치명적 버그 수정이나 직접 관련된 행사 일정이 사유가 되고, 버그 수정이라면 현재 버전에서의 재현 절차를 함께 내야 합니다. 남용하면 이후 요청이 거절될 수 있다고 지침에 적혀 있으므로 실제 장애에만 씁니다. 다른 하나는 버그 수정 제출입니다. 이미 스토어에 올라가 있는 앱의 버그 수정은 법적·안전 문제를 제외하면 다른 지침 위반 때문에 지연되지 않으며, 반려된 경우 심사팀에 이 절차를 적용받겠다고 알리고 해당 위반은 다음 제출에서 해결합니다(App Review Guidelines, App Review).

되돌리기가 어렵습니다

웹에서는 문제가 생기면 이전 버전으로 되돌리면 됩니다. 앱은 이미 설치된 것을 되돌릴 수 없습니다.

가능한 대응은 제한적입니다.

  • 수정 버전을 다시 심사에 올립니다 (시간이 걸립니다)
  • 서버에서 해당 기능을 끕니다 (그렇게 설계되어 있어야 가능합니다)
  • 스토어에서 내려 신규 설치만 막습니다 (이미 설치된 사용자에게는 영향이 없습니다)

두 번째가 현실적인 방어선입니다. 앱에서 위험한 기능은 서버 설정으로 끌 수 있게 만들어두는 것이 사고 시 유일한 즉시 대응 수단입니다.


2. 여러 버전이 동시에 돌아갑니다

업데이트를 내보내도 모두가 받지는 않습니다. 운영 중 앱은 항상 여러 버전이 섞여 있습니다.

서버는 구버전도 상대해야 합니다

새 버전에 맞춰 API를 바꾸면, 구버전 사용자의 앱이 동작하지 않게 됩니다.

원칙은 연동 설계와 같습니다.

  • 필드 추가는 괜찮습니다. 구버전은 모르는 필드를 무시하면 됩니다
  • 필드 삭제·의미 변경은 구버전을 깨뜨립니다
  • 응답 구조 변경도 마찬가지입니다

깨는 변경이 필요하면 API 버전을 나누고 구버전을 일정 기간 유지해야 합니다. 그 기간은 사용자들이 업데이트하는 속도에 달려 있으므로, 버전별 사용 비율을 볼 수 있어야 판단할 수 있습니다. 필드 추가와 삭제를 구분하는 기준은 외부 시스템 연동에서 장애가 생기는 자리 — 인터페이스 설계 원칙에서 다룬 내용과 같습니다.

깨는 변경을 내보내는 순서

웹은 서버와 화면을 함께 배포하면 끝나지만, 앱은 순서를 지켜야 합니다.

  1. 새 API 를 먼저 배포합니다. 기존 경로(예: /v1)는 그대로 두고 새 경로(예: /v2)를 추가합니다. 이 시점에는 아무 앱도 새 경로를 쓰지 않습니다.
  2. 새 경로를 쓰는 앱을 심사에 올립니다. 심사 기간 동안 서버는 두 경로를 모두 제공합니다.
  3. 단계적으로 배포하면서 버전 분포를 봅니다. 구버전 경로의 호출량이 줄어드는 속도를 확인합니다.
  4. 종료일을 정하고 구버전에 알립니다. 권장 업데이트 안내를 먼저 띄우고, 종료일 전에 필수 업데이트로 올립니다.
  5. 최소 지원 버전을 올립니다. 구버전 경로를 쓰는 앱이 더 이상 진입하지 못하게 한 뒤에 다음 단계로 넘어갑니다.
  6. 구버전 경로를 닫습니다. 바로 삭제하지 않고 "업데이트가 필요합니다"라는 응답을 일정 기간 남깁니다. 최소 지원 버전 확인을 거치지 않고 호출하는 경로(백그라운드 동기화, 위젯, 푸시 처리)가 남아 있을 수 있기 때문입니다.

5번과 6번의 순서가 바뀌면 사용자는 업데이트 안내 대신 원인 모를 오류 화면을 봅니다.

이 절차가 돌아가려면 서버가 요청마다 앱 버전을 알 수 있어야 합니다. 모든 요청에 버전 정보를 실어 보내는 방식이 가장 단순합니다. 아래는 헤더 이름을 임의로 정한 예시입니다.

GET /v2/orders HTTP/1.1
Host: api.example.com
X-App-Platform: android
X-App-Version: 2.3.1
X-App-Build: 231
X-OS-Version: 15

이 헤더를 접근 로그에 남기면 버전 분포 집계와 장애 분석에 같은 데이터를 쓸 수 있습니다. 구버전 경로를 닫은 뒤의 응답은 앱이 오류 코드로 구분할 수 있게 정해 둡니다. 앱은 이 코드를 받으면 일반 오류 화면 대신 업데이트 안내로 이동합니다.

{
  "error": {
    "code": "APP_UPDATE_REQUIRED",
    "message": "앱을 최신 버전으로 업데이트해 주세요.",
    "minimumVersion": "2.3.0"
  }
}

이 오류 코드 처리도 강제 업데이트와 마찬가지로 첫 버전에 들어가 있어야 합니다. 코드를 모르는 구버전 앱은 일반 오류로 표시할 수밖에 없습니다.

버전 분포를 측정합니다

의사결정에 필요한 정보입니다.

  • 버전별 활성 사용자 수
  • 신규 버전 전환 속도
  • 최소 지원 버전 이하 사용자 비율
  • OS 버전 분포

이 데이터가 없으면 "구버전 지원을 언제 끊을 수 있는가"를 답할 수 없습니다. 앱에서 접속할 때 버전 정보를 보내고 서버에서 집계하는 구조가 가장 단순합니다.

강제 업데이트를 설계에 넣습니다

특정 버전 이하는 사용할 수 없게 막아야 하는 경우가 생깁니다. 보안 문제나 서버 호환이 깨지는 변경이 대표적입니다.

필요한 요소입니다.

  • 서버가 최소 지원 버전을 내려줍니다
  • 앱은 실행 시 자기 버전과 비교합니다
  • 미달이면 업데이트 안내를 띄우고 진행을 막습니다
  • 권장 업데이트(건너뛸 수 있음)와 필수 업데이트(막음)를 구분합니다

이 기능은 첫 버전부터 넣어야 합니다. 나중에 추가하면, 그 기능이 없는 기존 버전에는 적용할 수 없습니다. 정작 필요한 순간에 쓸 수 없는 상황이 됩니다.

서버가 내려주는 버전 정책은 OS 별로 나눕니다. 두 스토어의 심사 통과 시점이 다르기 때문에, 한쪽만 새 버전이 나온 상태에서 최소 지원 버전을 올리면 다른 쪽 사용자는 받을 업데이트가 없는데도 막히게 됩니다. 아래는 응답 구조의 예시입니다.

{
  "android": {
    "minimumVersion": "2.1.0",
    "recommendedVersion": "2.3.1",
    "storeUrl": "https://play.google.com/store/apps/details?id=com.example.app"
  },
  "ios": {
    "minimumVersion": "2.1.0",
    "recommendedVersion": "2.3.0",
    "storeUrl": "https://apps.apple.com/app/id0000000000"
  },
  "maintenance": { "isActive": false, "message": "" }
}

구현할 때 놓치기 쉬운 점입니다.

  • 버전 비교는 문자열 비교가 아니라 숫자 단위 비교로 합니다. 문자열로 비교하면 2.10.0 이 2.9.0 보다 낮게 판정됩니다
  • 정책 조회에 실패했을 때의 동작을 정합니다. 조회 실패를 차단으로 처리하면 정책 서버 장애가 곧 앱 전체 장애가 됩니다. 마지막으로 받은 정책을 기기에 보관해 두고 그 값으로 판정하는 방식이 일반적입니다
  • 실행 시점뿐 아니라 백그라운드에서 돌아올 때도 확인합니다. 며칠씩 앱을 종료하지 않는 사용자가 있습니다
  • 최소 지원 버전은 해당 스토어에서 새 버전이 전체 사용자에게 열린 뒤에 올립니다. 단계적 배포 중에 올리면 아직 업데이트가 보이지 않는 사용자가 막힙니다

제로살롱 앱에서는 스플래시 화면에서 로그인 상태와 함께 필수 업데이트 여부를 확인하고, 필수와 선택을 구분해 처리했습니다. 수거기 앞에서 앱을 여는 사용자에게 건너뛸 수 있는 안내까지 진행을 막는 화면으로 띄우면 현장 흐름이 끊기기 때문입니다.

강제 업데이트를 걸지 판단하는 기준

강제 업데이트는 사용자를 막는 조치이므로 남용하면 이탈로 이어집니다. 상황별로 어느 수준을 쓸지 미리 정해 두면 운영 중에 매번 논쟁하지 않아도 됩니다.

상황 조치 판단 근거
인증·결제·개인정보와 관련된 보안 결함 필수 업데이트, 수정 버전 배포 즉시 사용자 비율과 무관하게 적용
구버전에서 데이터가 잘못 저장되는 결함 서버에서 해당 기능 차단 후 필수 업데이트 피해가 누적되는 문제는 차단이 먼저
서버 API 구버전 종료 권장 업데이트 후 종료일 전에 필수로 전환 구버전 사용자 비율이 합의한 기준 아래로 내려간 시점
법령·약관 변경으로 화면 수정이 필요 시행일 기준 필수 업데이트 시행일에서 심사 기간을 역산해 제출
신규 기능 추가, 디자인 개선 권장 업데이트 또는 안내 없음 막을 이유가 없음
특정 기기에서만 나는 오류 해당 조건에만 안내 전체를 막지 않음

최소 지원 버전을 올리기 전에는 다음을 확인합니다.

  • 대상 버전 이하의 활성 사용자 수와 비율을 확인했는가
  • 그 사용자들이 설치할 수 있는 새 버전이 스토어에 있는가. 새 버전이 지원 OS 범위를 올렸다면, 구형 OS 사용자는 업데이트할 수 없는 채로 막힙니다
  • 두 스토어 모두 새 버전이 전체 사용자에게 열려 있는가
  • 업데이트 안내 화면의 스토어 이동 링크가 실제로 동작하는가
  • 고객센터에 변경 일시와 안내 문구를 공유했는가

구형 OS 사용자를 막을 수밖에 없다면 "이 기기에서는 더 이상 지원되지 않습니다"라는 별도 안내와 웹 등 대체 경로를 준비합니다. 업데이트 버튼만 있는 화면은 이 사용자에게 막다른 길입니다.

스토어의 업데이트 기능은 보조 수단입니다

Android 에는 앱 안에서 업데이트를 받게 하는 Google Play 인앱 업데이트 기능이 있습니다. Android 5.0(API 수준 21) 이상에서 지원되며 두 가지 방식을 제공합니다(Android Developers: In-app updates, 2026년 10월 13일 확인).

방식 동작 맞는 경우
유연한(flexible) 업데이트 백그라운드에서 내려받고, 그동안 앱을 계속 사용 권장 업데이트
즉시(immediate) 업데이트 전체 화면으로 안내하고, 업데이트 후 재시작해야 계속 사용 필수 업데이트

출시할 때 Google Play Developer API 로 업데이트 우선순위(0~5, 기본값 0)를 지정하면 앱이 이 값을 읽어 방식을 고를 수 있습니다. 우선순위는 출시를 시작할 때만 정할 수 있고 나중에 바꿀 수 없습니다(In-app updates: Kotlin/Java).

이 기능은 Android 전용이고, 업데이트가 스토어에 있는지를 Google Play 가 판정합니다. "이 버전 이하는 사용할 수 없다"는 정책 판단은 여전히 서버의 몫입니다. 두 OS 에 같은 정책을 적용해야 하므로 서버가 판정하고, Android 에서는 인앱 업데이트를 안내 화면의 실행 수단으로 쓰는 구성이 관리하기 쉽습니다.

서버 주도 설정을 준비합니다

앱을 다시 배포하지 않고도 바꿀 수 있어야 하는 값들입니다.

  • 기능 켜고 끄기
  • 공지·점검 안내
  • API 서버 주소
  • 외부 링크
  • 문구 일부

배포 없이 바꿀 수 있는 범위가 넓을수록 운영이 수월합니다. 다만 모든 것을 서버에서 내려받게 하면 앱이 느려지고 복잡해지므로, 바뀔 가능성이 실제로 있는 값으로 한정하는 편이 좋습니다.

React Native 처럼 자바스크립트로 화면을 구성하는 앱은 스토어를 거치지 않고 코드 묶음을 교체하는 OTA 업데이트를 쓸 수 있습니다. 제로살롱 앱에서는 운영 콘텐츠를 서버에서 관리하고 OTA 업데이트를 함께 적용해, 문구 수정이나 간단한 화면 변경을 심사 대기 없이 반영했습니다.

이 수단에는 스토어 정책상의 한계가 있습니다. App Store 심사 지침 2.5.2 는 앱의 기능을 추가하거나 바꾸는 코드를 내려받아 실행하는 것을 금지하고, Google Play 는 Google Play 가 아닌 곳에서 실행 코드(dex, JAR, .so)를 내려받는 것을 금지하되 웹뷰의 자바스크립트처럼 인터프리터에서 도는 코드는 예외로 둡니다(App Review Guidelines, Google Play 기기 및 네트워크 악용 정책, 2026년 10월 13일 확인). OTA 의 용도는 오류 수정과 문구·화면 조정으로 한정하고, 심사받은 앱의 성격을 바꾸는 기능 추가는 스토어 심사를 거치도록 운영 기준을 나눠 두는 편이 안전합니다. 네이티브 코드나 권한이 바뀌는 변경은 기술적으로도 OTA 로 내보낼 수 없습니다.


3. 기기와 환경이 통제되지 않습니다

웹도 브라우저 차이가 있지만, 모바일은 범위가 더 넓습니다.

확인 범위를 먼저 합의합니다

계약 단계에서 정해두지 않으면 검수에서 분쟁이 생깁니다.

항목 정해야 할 내용
OS 버전 어디까지 지원하는가
화면 크기 최소·최대 해상도, 태블릿 지원 여부
대상 기기 검수에 쓸 실제 기기 목록
네트워크 저속 환경 동작 기준
접근성 글자 크기 확대, 화면 낭독 지원 범위

글자 크기 확대가 자주 누락됩니다. 시스템 설정에서 글자를 키운 사용자는 적지 않은데, 고정 높이로 만든 화면은 이때 깨집니다.

실제 기기에서 확인해야 하는 것들

시뮬레이터로는 잡히지 않는 문제들입니다.

  • 카메라·위치·생체 인증 등 하드웨어 기능
  • 푸시 알림 수신
  • 결제 흐름
  • 저사양 기기의 성능
  • 배터리 소모
  • 화면 노치·하단 제스처 영역과의 충돌

실기기 목록과 대여·구매 계획을 프로젝트 초기에 세워두는 편이 좋습니다.

네트워크가 끊긴 상태를 정의합니다

이동 중에 쓰는 앱은 네트워크가 수시로 끊깁니다. 웹보다 훨씬 자주 겪는 상황입니다.

화면별로 정해야 할 것들입니다.

  • 조회 화면 — 캐시된 내용을 보여줄 것인가, 빈 화면을 보여줄 것인가. 보여준다면 언제 받은 데이터인지 표시합니다
  • 입력 화면 — 작성 중이던 내용이 사라지지 않게 임시 저장합니다
  • 전송 실패 — 재시도할 것인가, 사용자에게 맡길 것인가
  • 복구 시점 — 네트워크가 돌아오면 자동으로 다시 시도할 것인가

작성 중이던 내용이 날아가는 것이 체감상 가장 나쁜 경험입니다. 긴 입력 폼이 있다면 로컬 임시 저장은 거의 필수입니다.

기기에 데이터를 저장한다면 무엇을 저장할지도 정해야 합니다. 개인정보나 인증 정보를 평문으로 남기면 기기 분실 시 문제가 됩니다. 민감한 값은 OS가 제공하는 보안 저장소를 쓰고, 로그아웃 시 정리하는 절차가 필요합니다.

앱 용량과 첫 실행 시간을 관리합니다

설치 용량이 크면 다운로드 자체를 포기하는 사용자가 생깁니다. 이동통신 환경에서는 특히 그렇습니다.

  • 이미지·폰트 등 리소스를 앱에 모두 넣을지, 나중에 받을지 정합니다
  • 쓰지 않는 라이브러리를 정리합니다
  • 첫 실행 시 보여줄 화면을 정합니다. 흰 화면이 몇 초 이어지면 오작동으로 받아들여집니다

백그라운드 동작에 제약이 있습니다

앱이 화면에 없을 때 무엇을 할 수 있는지는 OS가 통제합니다. 웹 서비스 감각으로 설계하면 어긋납니다.

  • 백그라운드에서 주기적으로 실행되는 작업은 보장되지 않습니다
  • 배터리 최적화 설정에 따라 동작이 달라집니다
  • 앱이 종료되면 예약한 작업이 사라질 수 있습니다

주기적 동기화나 위치 추적이 요구사항에 있다면, 실제로 어느 수준까지 가능한지 확인하고 기대치를 맞춰야 합니다. "항상 동작합니다"라고 약속하기 어려운 영역입니다.


4. 푸시 알림은 생각보다 복잡합니다

간단해 보이지만 설계 요소가 많습니다.

권한을 언제 요청할지 정합니다

설치 직후 바로 요청하면 거부율이 높습니다. 한 번 거부되면 다시 요청할 수 없고, 사용자가 설정에서 직접 켜야 합니다.

  • 알림이 왜 필요한지 먼저 설명하는 화면을 두는 방식
  • 알림이 실제로 유용해지는 시점에 요청하는 방식
  • 거부한 사용자에게 나중에 안내하는 경로

전달이 보장되지 않습니다

푸시는 확실한 전달 수단이 아닙니다.

  • 기기가 꺼져 있거나 네트워크가 없으면 지연되거나 유실됩니다
  • 사용자가 알림을 꺼두었을 수 있습니다
  • OS가 배터리 상태에 따라 지연시킬 수 있습니다

중요한 내용을 푸시에만 의존하면 안 됩니다. 앱 안에서도 확인할 수 있는 알림함을 두고, 정말 중요한 것은 문자나 이메일을 병행하는 구성이 안전합니다.

토큰을 관리해야 합니다

기기마다 발급되는 토큰이 있고, 이것이 바뀝니다.

  • 앱 재설치, 데이터 삭제 시 변경됩니다
  • 로그아웃 시 해당 토큰을 정리하지 않으면 다른 사람에게 알림이 갑니다
  • 한 사용자가 여러 기기를 쓸 수 있습니다
  • 오래 쓰이지 않은 토큰은 정리해야 합니다

로그아웃 시 토큰 정리 누락은 실제 사고로 이어집니다. 기기를 넘겨받은 사람이 이전 사용자의 알림을 받게 됩니다.

눌렀을 때 어디로 갈지 정합니다

알림을 눌렀는데 앱 첫 화면만 열리면, 사용자는 해당 내용을 다시 찾아야 합니다. 알림마다 이동할 화면을 지정하는 구조가 필요합니다.

정해야 할 것들입니다.

  • 알림 종류별 이동 대상 화면과 필요한 값
  • 로그인하지 않은 상태에서 눌렀을 때의 처리
  • 앱이 삭제된 뒤 눌렀을 때 (스토어로 보낼 것인가)
  • 권한이 없는 내용이면 어떻게 안내할 것인가

같은 구조가 외부 링크로 앱을 여는 경우에도 쓰입니다. 문자나 웹페이지의 링크를 눌러 앱의 특정 화면으로 들어오는 흐름입니다. 앱이 설치되어 있으면 앱으로, 없으면 웹이나 스토어로 보내는 분기가 필요하고, 이 설정은 서버와 도메인 쪽 작업이 함께 필요합니다.

마케팅이나 고객 응대에서 자주 요구되는 기능이라 요구사항에 명시되지 않아도 나중에 요청이 들어오는 경우가 많습니다. 초기에 범위를 확인해두는 편이 낫습니다.

발송량을 통제합니다

알림이 잦으면 사용자가 꺼버립니다. 한 번 꺼지면 되돌리기 어렵습니다.

  • 유형별로 수신 설정을 나눕니다
  • 심야 시간 발송을 제한합니다
  • 같은 내용을 반복 발송하지 않습니다
  • 발송 전 대상 수를 확인하는 절차를 둡니다

채널별 성격, 발송 시점, 수신 설정과 동의 관리는 알림이 무시되기 시작하는 지점 — 발송 시스템 설계에서 자세히 다뤘습니다.


5. 문제를 사용자보다 먼저 알아야 합니다

웹은 서버 로그로 상황을 파악할 수 있습니다. 앱은 사용자 기기에서 도는 코드라 그렇지 않습니다. 앱이 죽어도 서버는 모릅니다.

오류 수집 도구를 처음부터 넣습니다

앱이 비정상 종료되거나 예외가 발생했을 때 그 정보를 모으는 장치가 필요합니다. 수집해야 할 정보입니다.

  • 발생 지점과 호출 흐름
  • 앱 버전과 OS 버전
  • 기기 모델
  • 발생 빈도와 영향받은 사용자 수
  • 직전에 어떤 화면에 있었는지

이 도구는 출시 전에 넣어야 합니다. 문제가 생긴 뒤에 붙이면, 그 버전을 쓰는 사용자들의 상황은 끝내 알 수 없습니다.

개인정보가 함께 수집되지 않도록 하는 것도 확인 대상입니다. 오류 정보에 입력값이나 토큰이 섞여 올라가는 경우가 있습니다.

무엇을 심각한 문제로 볼지 정합니다

모든 오류에 대응할 수는 없습니다. 기준이 필요합니다.

등급 예시 대응
긴급 실행 즉시 종료, 결제 실패 즉시 수정 배포 또는 서버에서 기능 차단
높음 주요 기능 동작 불가 다음 배포에 포함
보통 특정 조건에서만 발생 우선순위에 따라 처리
낮음 화면 표시 문제 모아서 처리

비정상 종료율을 지표로 관리하면 판단이 쉬워집니다. 평소 수준을 알고 있어야 새 버전 배포 후 나빠졌는지 확인할 수 있습니다.

기준선을 정할 때 참고할 공식 수치가 있습니다. Google Play 는 Android vitals 에서 사용자가 체감한 비정상 종료율이 전체 기기 평균 1.09%, 단일 휴대전화 기종 기준 8% 를 넘으면 스토어 노출을 줄이거나 스토어 등록정보에 경고를 표시할 수 있다고 밝히고 있습니다. 집계에는 최근 28일 데이터를 씁니다(Android vitals, 2026년 10월 13일 확인). 이 값은 스토어가 불이익을 주기 시작하는 선이므로, 내부 대응 기준은 이보다 낮게 잡아야 합니다. 기종별 기준이 따로 있다는 점도 눈여겨볼 부분입니다. 전체 평균이 양호해도 특정 기종에서 집중적으로 죽는 앱은 그 기종에서 불이익을 받습니다.

단계적으로 배포합니다

새 버전을 전체 사용자에게 한 번에 내보내면, 문제가 있을 때 영향 범위가 최대가 됩니다.

  • 일부 사용자에게 먼저 배포하고 지표를 확인합니다
  • 이상이 없으면 비율을 올립니다
  • 문제가 발견되면 배포를 중단합니다

이미 받은 사용자는 되돌릴 수 없지만, 더 퍼지는 것은 막을 수 있습니다. 스토어가 제공하는 단계적 배포 기능을 쓰거나, 서버 설정으로 새 기능을 순차 개방하는 방식을 씁니다.

두 스토어의 단계적 배포는 동작이 다릅니다(2026년 10월 13일 확인).

항목 App Store 단계적 출시 Google Play 단계적 출시
대상 버전 업데이트. 자동 업데이트를 켠 사용자 중 무작위 표본 앱 업데이트만 가능. 최초 출시에는 쓸 수 없음
비율 7일간 1% → 2% → 5% → 10% → 20% → 50% → 100% 로 고정 출시할 때 비율을 지정하고 직접 올림
중단 일시 중지 가능. 합계 30일까지이며 횟수 제한은 없음 중단하면 추가 사용자에게 배포되지 않음. 이상이 없으면 재개 가능
이미 받은 사용자 그대로 유지 그대로 유지
우회 경로 단계적 출시 중에도 누구나 스토어에서 수동으로 받을 수 있음 공식 문서에 수동 설치 경로 언급 없음
문제 발견 시 일시 중지 후 수정 버전 제출 중단 후 수정한 번들로 새 출시를 만들어 배포

(App Store Connect 도움말: 단계적 출시, Play Console 고객센터: 단계적 출시)

운영 절차에 넣어야 할 점은 세 가지입니다.

  • App Store 의 단계적 출시는 노출 차단이 아닙니다. 스토어에서 직접 업데이트를 누른 사용자는 첫날부터 새 버전을 받습니다. 서버와 호환되지 않는 버전을 "1% 만 받았으니 괜찮다"고 볼 수 없습니다
  • Google Play 는 첫 출시에 단계적 출시를 쓸 수 없습니다. 첫 출시의 위험은 비공개·공개 테스트 단계에서 줄여야 합니다
  • 어느 쪽도 되돌리기 기능은 아닙니다. 중단은 확산을 멈출 뿐이고, 이미 받은 사용자를 구하려면 수정 버전을 다시 내거나 서버에서 기능을 꺼야 합니다

비율을 올리기 전에 볼 지표와 중단 기준은 배포 전에 정해 둡니다. 예를 들어 "새 버전의 비정상 종료율이 직전 버전보다 뚜렷하게 높으면 중단", "결제·로그인 실패율이 평소 범위를 벗어나면 중단"처럼 숫자로 판단할 수 있는 문장이어야 하고, 누가 중단을 결정하는지도 함께 정합니다. 표본이 작은 초기 비율에서는 지표가 흔들리므로, 비율을 올리는 간격은 판단에 필요한 사용자 수가 모이는 시간으로 잡습니다.

사용자 문의를 받을 경로를 둡니다

앱 안에 문의 수단이 있으면 문제 파악이 빨라집니다. 이때 앱 버전, OS 버전, 기기 정보를 자동으로 함께 보내도록 하면 확인 시간이 크게 줄어듭니다. 사용자에게 "어떤 기종 쓰시나요"를 묻는 왕복이 사라집니다.

스토어 리뷰도 확인 경로입니다. 다만 리뷰로 들어온 문제는 이미 여러 사용자가 겪은 뒤인 경우가 많습니다.


6. 스토어 정책과 계정이 프로젝트 자산입니다

기술 외적인 부분인데 일정에 자주 영향을 줍니다.

계정과 권한을 먼저 정리합니다

  • 스토어 개발자 계정은 발주사 명의로 만드는 것이 원칙입니다. 수행사 계정으로 올리면 나중에 이관이 번거롭습니다
  • 계정 생성과 사업자 확인에 시간이 걸립니다
  • 인증서·키를 누가 보관할지 정해야 합니다
  • 계정 접근 권한을 누구에게 줄지 정합니다

계정 준비는 개발과 무관하게 걸리는 시간이 있어서 착수 첫 주에 시작해야 합니다. 일정에 영향을 주는 요건입니다(2026년 10월 13일 확인).

항목 요건 일정상 의미
Apple Developer Program 조직 등록 계약 체결이 가능한 법인이어야 하고 D-U-N-S 번호가 필요(정부 기관 제외). 등록자는 조직을 법적으로 대리할 권한이 있어야 함. 조직 도메인의 웹사이트와 업무용 이메일 필요. 연 99달러 발주사 내부에서 등록 담당자와 권한 위임을 먼저 정해야 함
Google Play 조직 계정 D-U-N-S 번호 필수. 발급에 최대 30일이 걸릴 수 있음. 결제 프로필의 법인명·주소가 D-U-N-S 정보와 일치해야 함 D-U-N-S 보유 여부 확인이 가장 먼저 할 일
Google Play 신규 개인 계정 2023년 11월 13일 이후 만든 개인 계정은 테스터 12명 이상이 14일 이상 연속 참여한 비공개 테스트를 마쳐야 프로덕션 출시를 신청할 수 있음 개인 명의로 출시한다면 최소 2주와 테스터 모집 기간이 추가됨

(Apple Developer Program 등록, Play Console 고객센터: 계정 생성에 필요한 정보, Play Console 고객센터: 신규 개인 개발자 계정의 테스트 요건)

발주사가 법인이라면 조직 계정으로 등록하는 것이 맞고, 이 경우 비공개 테스트 요건은 적용되지 않습니다. 다만 대표자 개인 명의로 먼저 만들어 둔 계정이 있는 경우 이 요건에 걸리므로, 기존 계정이 있다면 유형과 생성 시점을 확인해야 합니다.

계정·인증서·키의 소유권을 표로 남깁니다

수행사가 바뀌거나 담당자가 퇴사했을 때 앱을 계속 배포할 수 있는지는 이 표가 있느냐에 달려 있습니다. 아래 항목을 채워 인수인계 산출물에 포함시킵니다.

자산 소유 주체 정해야 할 것 분실·만료 시 영향
Apple Developer 계정 (Account Holder) 발주사 계정 이메일을 개인이 아닌 조직 주소로, 2단계 인증 기기의 관리자 계정에 접근하지 못하는 동안 제출과 권한 관리가 막힘
App Store Connect 사용자 권한 발주사가 부여 수행사 인력에게 줄 역할과 회수 시점 퇴사자 계정이 남으면 보안 문제
iOS 배포 인증서 발주사 팀 생성 권한(Account Holder·Admin), 개인 키 보관 위치 만료·폐기되어도 스토어의 기존 앱은 영향 없음. 그 인증서로 서명한 새 빌드는 올릴 수 없음
APNs 인증서 또는 키 발주사 팀 발송 서버에 등록한 값과 갱신 담당자 인증서가 만료·폐기되면 푸시를 보낼 수 없음
Google Play 개발자 계정 발주사 소유자 계정, 사용자별 권한 법인 정보 불일치를 해결하지 않으면 계정이 제한될 수 있음
Android 앱 서명 키 Play 앱 서명 사용 시 Google 이 보관 Play 앱 서명 사용 여부 직접 관리하다 분실하면 재설정 불가
Android 업로드 키 발주사 (수행사가 위탁 보관 가능) 키스토어 파일과 비밀번호의 보관 위치, 접근 가능자 분실·유출 시 Play Console 에서 재설정 요청 가능
푸시·분석·오류 수집 서비스 계정 발주사 프로젝트 소유자, 결제 수단 수행사 계정에 묶여 있으면 이관 시 데이터 연속성이 끊길 수 있음
도메인, 앱 링크 설정 파일 발주사 도메인 관리자, 설정 파일 배포 담당 도메인 만료 시 딥링크와 처리방침 링크가 함께 끊김
소스 저장소, 빌드 설정, 환경 변수 계약에 따름 저장소 권한, 비밀 값의 전달 방식 빌드 재현 불가

(Apple: Certificates, Play Console 고객센터: Play 앱 서명, 2026년 10월 13일 확인)

Android 서명 키는 두 종류를 구분해야 합니다. Play 앱 서명을 쓰면 사용자에게 전달되는 앱에 서명하는 앱 서명 키는 Google 이 보관하고, 개발 측은 업로드용 키로 서명해 올립니다. 업로드 키는 분실하거나 유출되어도 새 키를 만들어 Play Console 에서 재설정을 요청할 수 있습니다. 반면 Play 앱 서명 없이 앱 서명 키를 직접 관리하다 분실하면 재설정할 방법이 없습니다. 같은 앱으로 업데이트를 이어갈 수 없게 되는 것은 이 경우입니다. 운영 중인 앱을 인수할 때는 어느 방식인지부터 확인하고, 키 보관 방법과 백업을 프로젝트 산출물에 포함시켜야 합니다.

키스토어 파일과 비밀번호, 인증서의 개인 키를 메신저나 이메일로 주고받는 일은 피해야 합니다. 비밀 관리 도구에 보관하고, 누가 접근할 수 있는지를 위 표에 함께 적습니다.

수행사 계정으로 이미 출시한 앱을 발주사 계정으로 옮기는 것은 두 스토어 모두 가능합니다. 다만 그대로 넘어오지 않는 것들이 있습니다.

  • App Store: 평점·리뷰와 번들 ID 는 유지되고 사용자는 계속 업데이트를 받습니다. 이전 전에 TestFlight 의 빌드와 테스터를 모두 지워야 하고, 넘기는 쪽은 앱 분석 데이터 접근을 잃으며, Apple Pay 판매자 ID 는 넘어가지 않습니다 (App Store Connect 도움말: 앱 이전)
  • Google Play: 사용자, 통계, 평점·리뷰, 구독은 넘어갑니다. 이전 전 주문은 원래 계정에 남아 환불을 그쪽에서 처리해야 하고, 비공개 테스트 그룹은 다시 만들어야 하며, 분석·푸시 등 연동 서비스 설정은 새 계정에서 다시 잡아야 합니다 (Play Console 고객센터: 앱 이전)

결제나 구독이 있는 앱일수록 이전 작업이 커집니다. 처음부터 발주사 계정으로 출시하는 편이 낫다고 말씀드리는 이유입니다.

정책 변경에 대응할 여지를 둡니다

스토어 정책은 바뀝니다. 개인정보 수집 항목 고지 방식, 광고 식별자 사용, 계정 삭제 기능 제공 같은 요건이 추가되어 왔습니다.

  • 정책 변경 공지를 받을 담당자를 정합니다
  • 대응 기한이 있는 요건은 일정에 반영합니다
  • 유지보수 계약에 정책 대응 범위를 명시합니다

마지막 항목이 실무적으로 중요합니다. 운영 중 정책이 바뀌어 수정이 필요할 때, 그것이 하자보수인지 추가 개발인지를 두고 논쟁이 생깁니다. 계약 단계에서 구분해두는 편이 낫습니다. 범위를 문서로 구분하는 방법은 SI 프로젝트에서 범위가 불어나는 구조와 이를 막는 변경관리 설계에서 따로 다뤘습니다.

지금 적용되는 주요 요건

아래는 2026년 10월 13일에 각 공식 문서에서 확인한 내용입니다. 스토어 정책은 예고 후 바뀌므로, 제출 전에 원문을 다시 확인해야 합니다.

영역 App Store Google Play
빌드 도구·대상 버전 2026년 4월 28일부터 Xcode 26 이상, iOS 26 등 26 계열 SDK 로 빌드해야 업로드 가능 2026년 8월 31일부터 신규 앱과 업데이트는 Android 16(API 수준 36) 이상을 대상으로 해야 제출 가능. 2026년 11월 1일까지 연장 요청 가능
기존 앱 - Android 15(API 수준 35) 이상을 대상으로 하지 않으면 대상 수준보다 높은 Android 버전의 신규 사용자에게 노출되지 않음
계정 삭제 계정 생성을 지원하는 앱은 앱 안에서 삭제를 시작할 수 있어야 함. 비활성화만 제공하는 것은 불충분. 전화·이메일 등 고객 지원 절차를 요구할 수 없음(고도 규제 산업 제외) 앱 안의 삭제 경로와 함께, 앱을 다시 설치하지 않고도 삭제를 요청할 수 있는 웹 링크를 제공해야 함
수집 정보 고지 신규 앱과 업데이트 제출 시 App Store Connect 에 개인정보 처리 내용을 입력 내부 테스트만 하는 앱을 제외하고 데이터 보안 양식 작성 필수. 수집하는 데이터가 없어도 작성
서드파티 SDK 필수 사유 API 를 쓰면 승인된 사유를 프라이버시 매니페스트에 선언해야 업로드 가능(2024년 5월 1일부터, SDK 코드 포함). Apple 이 지정한 SDK 를 새로 넣을 때는 해당 SDK 의 매니페스트와 서명 필요 SDK 가 수집·공유하는 데이터도 개발자가 양식에 반영할 책임이 있음
추적·광고 식별자 iOS 14.5 이상에서 사용자를 추적하거나 광고 식별자에 접근하려면 앱 추적 투명성(ATT) 허용을 받아야 함. 허용 전 식별자 값은 0 으로 채워짐 -

출처는 Apple: Upcoming Requirements, Google Play 대상 API 수준 요구사항, Apple: 앱 내 계정 삭제 제공, Google Play 계정 삭제 요건, Apple: User privacy and data use, Google Play 데이터 보안 섹션, Apple: 서드파티 SDK 요건입니다.

설계와 일정에 영향을 주는 부분을 짚어 보겠습니다.

계정 삭제는 화면 하나로 끝나지 않습니다. 삭제 요청을 받으면 계정과 연결된 데이터를 실제로 지워야 하고, 법령상 보관해야 하는 데이터가 있다면 무엇을 얼마나 보관하는지 사용자에게 알려야 합니다. Apple 의 안내에 따르면 자동 갱신 구독이 있는 사용자에게는 결제가 Apple 을 통해 계속된다는 점을 알려야 하고, Apple 로그인을 쓰는 앱은 삭제 시 토큰을 폐기해야 하며, 가입 절차 없이 자동으로 만들어지는 게스트 계정도 삭제 대상입니다. 저희가 구축한 광고 리워드 앱에서는 계정 삭제 요청을 관리자 콘솔의 별도 화면에서 처리해 요청과 처리 결과가 기록으로 남도록 했습니다. 포인트와 출금처럼 금전이 걸린 서비스는 삭제 전에 정리할 것이 있어서, 요청 접수와 처리 사이의 상태를 관리해야 하기 때문입니다.

수집 정보 고지는 실제 동작과 맞아야 합니다. Google Play 는 고지 내용의 정확성을 개발자 책임으로 두고 있고, 불일치가 확인되면 업데이트 차단이나 삭제 조치를 할 수 있다고 밝히고 있습니다. 분석·광고·오류 수집 SDK 가 보내는 데이터까지 포함되므로, SDK 를 추가하거나 버전을 올릴 때마다 고지 내용을 다시 확인하는 절차가 필요합니다. 개인정보 처리방침, 스토어 고지, 권한 요청 문구 세 곳의 내용이 서로 어긋나지 않는지도 함께 봅니다.

크로스플랫폼도 예외가 아닙니다. Apple 이 지정한 SDK 목록에는 Flutter 와 다수의 Flutter 플러그인, Firebase 계열 SDK, React Native 가 쓰는 자바스크립트 엔진 Hermes 가 들어 있습니다. 프레임워크와 플러그인 버전이 오래되면 매니페스트가 빠져 있을 수 있으므로, 제출 직전이 아니라 개발 중에 의존성 버전을 점검합니다.

대상 버전 상향은 매년 옵니다. Google Play 는 2025년 8월 31일에 API 수준 35, 2026년 8월 31일에 36 으로 기준을 올렸고, Apple 도 2023년, 2024년, 2026년 4월에 업로드에 필요한 Xcode 최소 버전을 올렸습니다. 대상 API 수준을 올리면 권한, 백그라운드 동작, 화면 표시 방식의 기본 동작이 달라질 수 있어서 빌드 설정만 바꾸는 작업으로 끝나지 않는 경우가 많습니다. 전체 기능 회귀 확인을 포함한 작업으로 견적에 넣어야 합니다.

심사 정보를 산출물로 남깁니다

  • 앱 설명, 스크린샷, 키워드
  • 연령 등급 설문 답변
  • 개인정보 처리방침 링크
  • 심사용 계정 정보
  • 문의 연락처

이 내용이 정리되어 있지 않으면 담당자가 바뀔 때마다 다시 만들게 됩니다.


7. 자주 나오는 질문

네이티브와 크로스플랫폼 중 무엇을 골라야 합니까

판단 기준입니다.

조건 적합한 선택
하드웨어 기능을 깊게 쓴다 네이티브
화면 위주이고 두 OS가 같은 동작 크로스플랫폼
한쪽 OS만 우선 출시 둘 다 가능
장기 유지보수 인력 확보 팀 역량에 맞는 쪽

크로스플랫폼을 선택해도 OS별로 다르게 동작하는 영역은 남습니다. 푸시, 권한, 결제, 백그라운드 동작이 대표적입니다. "한 번 만들면 양쪽이 끝난다"는 기대는 맞지 않습니다.

웹뷰로 만들면 안 됩니까

일부를 웹뷰로 구성하는 것은 일반적입니다. 약관, 공지, 자주 바뀌는 콘텐츠가 대표적입니다. 배포 없이 수정할 수 있다는 장점이 큽니다.

다만 앱 전체가 웹사이트를 감싸기만 한 형태는 심사에서 문제가 될 수 있습니다. 스토어가 요구하는 것은 앱으로서의 가치입니다. App Store 심사 지침 4.2 는 앱이 웹사이트를 다시 포장한 수준을 넘는 기능, 콘텐츠, UI 를 갖춰야 한다고 적고 있습니다(App Review Guidelines). 네이티브 기능이 전혀 없는 구성이라면 사전에 검토가 필요합니다.

웹을 본체로 두는 구성 자체가 불가능한 것은 아닙니다. 광고 리워드 앱은 핵심 기능을 웹에 구현하고 앱이 이를 감싸는 구조로 만들되, 푸시 알림과 결제 앱 연동, 소셜 로그인의 외부 브라우저 처리와 딥링크 복귀는 앱 계층에서 다뤘습니다. 웹뷰 안에서는 소셜 로그인과 결제가 그대로 동작하지 않는 경우가 있어, 이 흐름만큼은 앱이 맡아야 했습니다. 웹으로 할 수 있는 것과 앱이어야 하는 것을 먼저 나누고, 앱이 맡는 부분이 무엇인지 심사 메모에서도 설명할 수 있어야 합니다.

앱과 웹을 동시에 만들면 비용이 줄어듭니까

서버와 API는 공유하므로 그 부분은 줄어듭니다. 화면은 대체로 각각 만들어야 합니다.

같이 진행할 때 유의할 점입니다.

  • 두 클라이언트가 같은 API를 쓰므로 변경 영향이 두 배가 됩니다
  • 화면 흐름이 달라지는 부분을 초기에 정해야 합니다
  • 배포 주기가 다릅니다. 웹은 바로, 앱은 심사를 거칩니다

배포 주기 차이를 고려하지 않으면, 서버를 바꿨는데 앱만 심사 대기 중이라 동작하지 않는 상황이 생깁니다. 서버 변경은 앱 배포가 완료된 뒤 켜지도록 설계하는 편이 안전합니다.

검수는 어떻게 진행합니까

웹처럼 URL을 공유해서 확인할 수 없다는 점이 다릅니다. 검수용 배포 경로를 먼저 마련해야 합니다.

  • 스토어를 거치지 않는 내부 배포 수단을 씁니다
  • 검수자에게 설치 방법을 안내해야 합니다. 기술에 익숙하지 않은 담당자라면 이 과정 자체가 장벽이 됩니다
  • 버전을 올릴 때마다 재설치가 필요한지, 자동으로 갱신되는지 확인합니다
  • 검수 의견에 앱 버전과 기기 정보를 함께 적도록 양식을 정합니다

마지막 항목이 없으면 "안 돼요"라는 의견만 쌓입니다. 어느 버전의 어느 기기에서 발생했는지를 모르면 재현할 수 없습니다.

검수 기간도 웹보다 여유 있게 잡는 편이 좋습니다. 수정 후 다시 확인하는 데 배포 시간이 매번 추가되기 때문입니다.

출시 후 유지보수는 어느 정도 필요합니까

앱은 방치하면 동작하지 않게 됩니다.

  • OS 메이저 업데이트마다 동작 확인이 필요합니다
  • 스토어가 요구하는 최소 대상 버전이 주기적으로 올라갑니다
  • 사용 중인 라이브러리의 지원이 종료됩니다
  • 인증서·키가 만료됩니다

연 1~2회는 기능 변경 없이도 갱신 배포가 필요하다고 보는 편이 현실적입니다. 유지보수 계약에 이 작업이 포함되는지 확인해두어야 합니다.

방치했을 때 실제로 일어나는 일은 스토어마다 다릅니다. Google Play 에서는 대상 API 수준이 기준보다 낮은 기존 앱이 최신 Android 기기의 신규 사용자에게 보이지 않게 됩니다. App Store 에서는 기존 앱은 남아 있지만, 요구되는 Xcode 버전으로 빌드하지 않으면 급한 버그 수정조차 올릴 수 없습니다(6장의 요건 표 참고). 장애가 났을 때 빌드 환경부터 올려야 하는 상황을 피하려면, 스토어 요건이 바뀌는 시기에 맞춰 정기 갱신을 잡아 두는 편이 낫습니다.


8. 착수 전 점검 목록

일정

  • 심사 소요와 반려 가능성을 일정에 반영했는가
  • 내부 배포 수단으로 시연할 계획이 있는가
  • 계정 생성과 사업자 확인 시간을 확보했는가

버전 관리

  • 강제 업데이트 기능을 첫 버전에 포함했는가
  • 최소 지원 버전을 서버에서 내려주는가
  • 버전별 사용자 분포를 집계하는가
  • API 변경 시 구버전 호환 정책이 있는가
  • 서버 설정으로 기능을 끌 수 있는가

환경

  • 지원 OS 버전과 기기 범위가 합의되어 있는가
  • 실기기 확인 목록과 확보 계획이 있는가
  • 글자 크기 확대 시 화면이 깨지지 않는가
  • 백그라운드 동작 요구사항의 실현 가능성을 확인했는가

푸시

  • 권한 요청 시점과 사전 안내를 설계했는가
  • 앱 내 알림함이 있는가
  • 로그아웃 시 토큰을 정리하는가
  • 유형별 수신 설정과 발송 시간 제한이 있는가

계정·정책

  • 스토어 계정이 발주사 명의인가
  • 서명 키 보관과 백업 방법이 정해져 있는가
  • 심사 정보가 문서로 남아 있는가
  • 정책 변경 대응이 유지보수 범위에 명시되어 있는가
  • D-U-N-S 번호 보유 여부와 계정 유형(조직·개인)을 확인했는가
  • 계정·인증서·키의 소유권 표를 작성했는가

9. 스토어 제출 전 점검 목록

착수 전 목록이 설계에 관한 것이라면, 이 목록은 제출 버튼을 누르기 전에 확인하는 것입니다. 버전마다 반복해서 씁니다.

심사 정보

  • 심사용 계정으로 실제 로그인이 되는가. 본인 인증이나 문자 인증이 필요한 앱이면 심사자가 통과할 방법을 마련했는가
  • 심사 기간 동안 서버가 켜져 있고 점검 일정과 겹치지 않는가
  • 심사 메모에 이번 버전의 변경 사항과 확인 방법을 구체적으로 적었는가
  • 특정 기기나 장비가 있어야 확인되는 기능은 시연 영상을 준비했는가
  • 스크린샷과 앱 설명이 실제 화면과 일치하는가

앱 상태

  • 준비 중 화면, 동작하지 않는 버튼, 테스트용 문구가 남아 있지 않은가
  • 앱 안의 모든 링크가 열리는가. 고객 지원 링크와 개인정보 처리방침 링크를 포함합니다
  • 최신 OS 버전의 실기기에서 실행해 보았는가
  • 권한을 모두 거부한 상태에서도 앱이 종료되지 않고 안내가 나오는가
  • 권한 요청 문구가 무엇에 쓰는지 구체적으로 설명하는가

개인정보·정책

  • 가입이 가능한 앱이면 앱 안에서 계정 삭제를 시작할 수 있는가
  • Google Play 에 계정 삭제 요청용 웹 링크를 등록했는가
  • 스토어의 수집 정보 고지가 이번 버전에 포함된 SDK 기준으로 맞는가
  • 개인정보 처리방침, 스토어 고지, 권한 문구의 내용이 서로 일치하는가
  • 연령 등급 설문 답변이 현재 콘텐츠와 맞는가
  • 디지털 재화 결제가 있다면 인앱결제 적용 여부를 판정했는가

빌드·배포

  • 스토어가 요구하는 빌드 도구와 대상 버전을 충족하는가
  • 버전 이름과 빌드 번호를 올렸는가
  • 운영 서버 주소와 운영용 키로 빌드했는가
  • 오류 수집 도구가 이 빌드에서 동작하는가
  • 이 버전이 쓰는 서버 API 가 운영 환경에 이미 배포되어 있는가
  • 단계적 출시 여부, 중단 기준, 중단 결정권자를 정했는가
  • 출시 후 최소 지원 버전을 올릴 계획이 있다면 그 시점을 정했는가

마치며

앱 프로젝트에서 어려운 부분은 화면을 만드는 일이 아닙니다. 고친 것이 곧바로 반영되지 않는다는 전제 위에서 설계하는 일입니다.

이 전제를 받아들이면 필요한 장치가 분명해집니다. 강제 업데이트를 첫 버전에 넣고, 위험한 기능은 서버에서 끌 수 있게 하고, 구버전과 호환되는 방식으로 API를 바꾸고, 버전 분포를 측정합니다. 각각은 큰 작업이 아니지만, 없으면 사고가 났을 때 할 수 있는 일이 없습니다.

저희는 웹과 연동되는 모바일 앱과 현장 단말용 네이티브 앱을 여러 차례 구축해왔습니다. 앱 프로젝트를 준비하고 계시다면 편하게 문의해주세요.


함께 보면 좋은 글

참고 자료

스토어 정책과 수치는 2026년 10월 13일에 확인한 내용입니다. 정책은 예고 후 바뀌므로 제출 전에 원문을 다시 확인하시기 바랍니다.