$ cd /blog
오류 해결

iOS 앱에서 ATT 추적 동의창이 안 뜰 때 — 앱 active 대기 함정 (앱스토어 심사 리젝 해결기)

AdMob 앱을 올렸더니 '추적 동의(ATT) 창이 안 뜬다'며 앱스토어 심사에서 리젝됐습니다. 코드는 멀쩡한데 왜 안 뜰까요? 앱이 foreground active 되기 전에 요청해서 iOS가 조용히 무시하는 함정과, 짧은 대기 한 줄로 해결한 실제 방법을 정리했습니다.


안녕하세요. Jay입니다!

AdMob 광고를 붙인 앱을 앱스토어에 올렸더니, 예상 못 한 사유로 리젝을 받았습니다. "추적 투명성(ATT) 동의창이 나타나지 않는다" 는 Guideline 2.1이었죠. 분명히 코드에는 추적 동의 요청을 넣어놨고, 제 아이폰에서는 잘 떴는데 말입니다. 오늘은 이 "코드는 맞는데 프롬프트가 안 뜨는" 함정을 어떻게 잡았는지 공유합니다.

🔍 코드는 맞는데 왜 안 뜰까

ATT(App Tracking Transparency) 프롬프트는 iOS가 아주 까다롭게 다룹니다. 핵심 규칙이 하나 있는데, 앱이 foreground에서 완전히 active 상태일 때만 iOS가 이 창을 띄워준다는 것입니다. 아직 앱이 뜨는 중(inactive)이면, requestTrackingAuthorization을 호출해도 iOS가 에러도 없이 그냥 조용히 무시해 버립니다.

문제는 여기서 생깁니다. 광고 SDK를 쓰면 보통 이런 순서로 초기화합니다.

  1. 앱 첫 프레임 직후 UMP(개인정보 동의) 정보 갱신
  2. 이어서 ATT 추적 동의 요청
  3. 그다음 광고 초기화

제 아이폰에서는 잘 떴던 이유가 바로 UMP 동의창이었습니다. EEA 등 동의가 필요한 지역에서는 UMP 창이 먼저 뜨면서 시간이 벌리고, 그사이 앱이 active가 되어 ATT가 정상적으로 떴던 거죠. 그런데 앱 심사 리뷰 환경은 UMP 동의가 필요 없는 조건이라, UMP 창 없이 cold launch 직후 곧바로 ATT를 호출합니다. 이때 앱이 아직 active 전이라 iOS가 프롬프트를 삼켜버린 겁니다.

즉 "내 폰에선 되는데 심사에선 안 뜬다"는 건 버그가 아니라 타이밍 문제였습니다.

🛠 해결 — active가 될 때까지 짧게 기다린 뒤 요청

고친 건 딱 한 가지입니다. ATT를 요청하기 직전에 짧은 지연을 줘서, 앱이 foreground active가 되는 걸 보장했습니다. 저는 600ms 정도로 충분했습니다.

final status = await AppTrackingTransparency.trackingAuthorizationStatus;
if (status == TrackingStatus.notDetermined) {
  // 앱이 active 될 때까지 잠깐 대기 → iOS가 프롬프트를 무시하지 않게
  await Future.delayed(const Duration(milliseconds: 600));
  await AppTrackingTransparency.requestTrackingAuthorization();
}

포인트는 두 가지입니다.

  • notDetermined일 때만 호출: 이미 허용/거부한 사용자에게 다시 묻지 않습니다.
  • 요청 전 짧은 대기: cold launch 직후 곧바로 부르지 않고, active 상태를 확보한 뒤 띄웁니다. UMP 동의창이 뜨는 지역이든 아니든 동일하게 동작하게 됩니다.

더 엄밀하게 하려면 지연 대신 WidgetsBinding.instance.lifecycleStateresumed인지 확인하거나, active로 바뀌는 시점을 감지해 요청할 수도 있습니다. 다만 실무에서는 짧은 지연 한 줄로도 안정적으로 해결됐습니다.

⚠️ iPad에서 꼭 다시 확인하세요

제 경우 1차 수정 후에도 iPad에서 다시 리젝을 받았습니다. 리뷰어가 아이폰이 아니라 iPad로 심사하면서 같은 미표시가 재현된 거죠. 그래서 마지막 검증은 반드시 iPad 시뮬레이터(또는 실기기) 에서 했습니다. iPad Pro 시뮬레이터로 앱을 새로 설치해 cold launch → ATT 프롬프트가 실제로 뜨는지 눈으로 확인하고 나서야 재제출했습니다.

한 가지 팁을 더하면, ATT는 한 번 결정하면 다시 안 뜨기 때문에 재현 테스트할 때는 앱을 지웠다 다시 설치해서 notDetermined 상태로 되돌린 뒤 확인해야 합니다.

결론

ATT 프롬프트는 "부르면 뜨는 것"이 아니라, "앱이 active일 때만 뜨는 것"입니다.

내 폰에선 잘 뜨는데 앱 심사에서 "ATT가 안 뜬다"고 리젝됐다면, 십중팔구 UMP 동의창이 없는 환경에서 앱이 active 되기 전에 요청하고 있는 겁니다. 요청 직전에 짧은 대기를 넣어 active를 보장하고, 검증은 iPad에서 앱을 새로 설치해 확인하세요. 다음에도 유익한 포스팅으로 찾아오겠습니다. 감사합니다!

📚 참고 / 출처

#iOS#ATT#App Tracking Transparency#UMP#AdMob#앱심사

$ ls related/

더 많은 IT·AI 활용법이 궁금하다면?

매주 새로운 실전 가이드가 업데이트됩니다.

전체 글 보기