# ITMS-91053 오류 Expo에서 해결하기

> ITMS-91053은 사유 필수 API 미선언 오류예요. ios.privacyManifests에 선언하고 다시 빌드하세요.

원본 페이지: [ITMS-91053 오류 Expo에서 해결하기](https://devoria.fr/ko/blog/itms-91053-missing-api-declaration-expo)
작성자: [Mehdi Azizi](https://devoria.fr/ko/mehdi-azizi)
게시일: 2026-10-25
최종 내용 수정: 2026-10-25


ITMS-91053은 Apple의 자동 검사로, [빌드를 업로드한 뒤](https://devoria.fr/ko/blog/eas-submit-ios-publish-expo-app-store) 이메일로 와요. 앱 코드가 "사유 필수(required reason)" API(환경설정, 파일 타임스탬프, 부팅 후 경과 시간, 디스크 공간, 키보드)를 쓰는데 개인정보 매니페스트에 그 이유를 설명하지 않았다는 뜻이에요. **Expo에서는 `ios.privacyManifests`에서 고쳐요. Apple이 지목한 카테고리, 실제 사용 방식을 설명하는 코드를 넣고 새로 빌드하면 돼요.**

미니게임 알람 앱인 Solys에서는 이 사유들을 앱 설정에 선언해 두었어요. 실제 선언 내용, 의존성이 쓰는 API를 나열하는 명령어, 그리고 제출 전에 최종 파일에서 확인할 점을 소개할게요.

## ITMS-91053 오류는 무슨 뜻인가요?

메시지 제목은 "ITMS-91053: Missing API declaration"이에요. 빌드의 특정 파일 코드가 사유가 필요한 API를 하나 이상 참조한다는 내용이고, 이어서 해당 카테고리를 나열해요. 예를 들면 `NSPrivacyAccessedAPICategoryUserDefaults`처럼요.

이 API들은 사용자에게 권한을 요청하지 않아요. 하지만 기기를 식별하는 데 쓰일 수 있어요. Apple은 이걸 fingerprinting이라고 불러요. 사용자가 추적에 동의해도 금지예요. Apple은 [사유 필수 API](https://developer.apple.com/documentation/bundleresources/describing-use-of-required-reason-api) 페이지에서 이렇게 설명해요. 모든 앱과 SDK는 이 API를 왜 쓰는지 선언해야 해요.

같은 페이지에 규칙도 나와 있어요. **2024년 5월 1일부터 App Store Connect는 매니페스트에 이 사용 내역을 설명하지 않은 앱을 받지 않아요.** 일부 개발자는 이 이메일을 승인된 빌드에서 단순 경고로 받았다고 해요. 그걸 믿지 마세요. 차단으로 여기고 다음 제출 전에 고치세요.

다른 ITMS 오류처럼 이건 리뷰어의 리젝이 아니에요. 아무도 앱을 열어보지 않았어요. Apple이 바이너리를 분석한 거예요.

## iOS 개인정보 매니페스트: PrivacyInfo.xcprivacy 파일

개인정보 매니페스트는 `PrivacyInfo.xcprivacy`라는 파일로, 앱 번들 루트에 있어요. [Apple의 privacy manifest 문서](https://developer.apple.com/documentation/bundleresources/privacy-manifest-files)에 따르면 수집하는 데이터, 추적, 사유 필수 API를 설명해요. 사유 필수 API는 `NSPrivacyAccessedAPITypes` 배열에 들어가요. 카테고리마다 항목 하나씩, 타입과 사유 목록을 함께 적어요.

함정이 하나 있어요. **매니페스트는 자기 번들만 커버해요.** Apple도 명시해요. 이 API를 쓰는 실행 파일이나 동적 라이브러리는 각자 번들에 매니페스트가 있어야 해요. 앱의 매니페스트는 내장된 프레임워크를 커버하지 않고, SDK도 앱의 매니페스트에 기댈 수 없어요.

[ITMS-90683](https://devoria.fr/ko/blog/itms-90683-missing-purpose-string-expo)이 요구하는 Info.plist 문구와 헷갈리지 마세요. 그 문구는 권한 요청 창에서 사용자에게 보여요. 매니페스트는 Apple만 읽어요.

## API 5개 카테고리와 사유 코드

카테고리의 전체 이름은 `NSPrivacyAccessedAPICategory`로 시작해요. API와 사유 목록은 [NSPrivacyAccessedAPIType](https://developer.apple.com/documentation/bundleresources/app-privacy-configuration/nsprivacyaccessedapitypes/nsprivacyaccessedapitype) 키 페이지에 있어요(2026년 10월 15일 확인).

| 카테고리        | 대표 API                     | 흔한 사유 |
| --------------- | ---------------------------- | --------- |
| UserDefaults    | `UserDefaults`               | CA92.1    |
| FileTimestamp   | `creationDate`               | C617.1    |
| SystemBootTime  | `systemUptime`               | 35F9.1    |
| DiskSpace       | `volumeAvailableCapacityKey` | E174.1    |
| ActiveKeyboards | `activeInputModes`           | 54BD.1    |

가장 자주 보게 될 코드예요.

- **CA92.1**: 앱이 다른 앱은 접근할 수 없는 자체 환경설정을 읽고 써요.
- **1C8F.1**: 같은 App Group의 위젯이나 익스텐션과 환경설정을 공유해요.
- **C617.1**: 앱 컨테이너 안에 있는 파일의 날짜나 크기를 읽어요.
- **3B52.1**: 사용자가 선택한 파일이에요. 예를 들면 문서 선택기에서요.
- **35F9.1**: 앱 안의 두 이벤트 사이 경과 시간을 재거나 타이머를 돌려요.
- **E174.1**: 파일을 쓰기 전에 남은 공간을 확인하고, 그 결과가 사용자에게 보여요.
- **85F4.1**: 사용자에게 디스크 공간을 표시해요.

**가장 넓어 보이는 사유가 아니라 실제 사용 방식에 맞는 사유를 선언하세요.** Apple은 이 API와 데이터를 선언한 사유로만 써야 하고, 절대 추적에 쓰면 안 된다고 밝혀요. C56D.1과 0A2A.1 두 코드는 서드파티 SDK 전용이에요. 앱 매니페스트에 넣으면 안 돼요.

## Expo에서 개인정보 매니페스트 선언하기

Expo에서는 파일을 직접 쓰지 않아요. app.json이나 app.config의 `expo.ios.privacyManifests` 아래에 내용을 적으면 prebuild가 `PrivacyInfo.xcprivacy`를 생성해요. [Expo의 privacy manifest 문서](https://docs.expo.dev/guides/apple-privacy/)에 나온 방법이에요.

Solys 설정에서 실제로 가져온 부분이에요. 이 키에는 추적과 수집 데이터도 들어 있는데 여기서는 뺐어요.

```json
{
  "expo": {
    "ios": {
      "privacyManifests": {
        "NSPrivacyAccessedAPITypes": [
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
            "NSPrivacyAccessedAPITypeReasons": ["CA92.1", "1C8F.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryFileTimestamp",
            "NSPrivacyAccessedAPITypeReasons": ["C617.1"]
          },
          {
            "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategorySystemBootTime",
            "NSPrivacyAccessedAPITypeReasons": ["35F9.1"]
          }
        ]
      }
    }
  }
}
```

CA92.1, C617.1, 35F9.1은 React Native와 앱의 Expo 모듈이 선언한 내용을 그대로 옮긴 거예요. 1C8F.1은 Solys 자체에서 나와요. 앱이 App Group으로 위젯과 설정을 공유하거든요.

알아둘 함정이 있어요. `ios` 폴더가 생성되고 git에서 무시된다면 **그 폴더에 직접 쓴 `PrivacyInfo.xcprivacy`는 절대 빌드에 들어가지 않아요.** EAS가 prebuild를 다시 실행해서 폴더를 새로 만들거든요. 2026년 9월 9일에 제 프로젝트 하나에서 확인했어요. 직접 쓴 매니페스트가 prebuild 후에 사라졌어요. 선언은 설정 안에 있어야 해요.

마지막으로, 매니페스트는 바이너리의 일부예요. 원격 업데이트로는 바뀌지 않아요. 다시 빌드해서 제출해야 해요.

## 자체 매니페스트를 포함한 서드파티 SDK

최근 라이브러리는 대부분 자체 매니페스트를 제공해요. 이 API를 쓰는 Expo 패키지는 `ios` 폴더에 `PrivacyInfo.xcprivacy`가 있고, React Native도 마찬가지예요. 문제는 이것들이 앱에 링크되는 방식이에요.

Expo 문서는 이렇게 경고해요. Apple은 정적으로 링크된 CocoaPods 의존성의 매니페스트를 전부 제대로 읽지는 못하는데, Expo 패키지가 바로 그 경우예요. 그래서 그 사유들을 앱 설정에 옮겨 적어야 할 수도 있어요.

이 작업을 줄이려면 [expo-build-properties](https://docs.expo.dev/versions/latest/sdk/build-properties/)의 `ios.privacyManifestAggregationEnabled` 설정이 CocoaPods 의존성의 매니페스트를 파일 하나로 합쳐줘요. 제 프로젝트(SDK 57)에서 Expo가 생성한 Podfile에서는 이 병합이 기본으로 켜져 있어요. 직접 끄지 않는 한요.

병합에는 한계가 있어요. 매니페스트를 제공하는 의존성만 보여요. 매니페스트가 없는 오래된 라이브러리는 안 보여요. **그러니 이메일에 적힌 파일 경로를 읽으세요.** 어디를 고칠지 알려줘요.

| 지목된 파일       | 고칠 곳                |
| ----------------- | ---------------------- |
| 앱 실행 파일      | `ios.privacyManifests` |
| `.framework`      | SDK 업데이트           |
| `.appex` 익스텐션 | 익스텐션의 매니페스트  |

## 제출 전에 확인하기

Expo는 제출 후 Apple의 이메일을 기다려보라고 해요. 그것도 되지만 왕복할 때마다 빌드 하나가 들어가요. 제가 미리 하는 확인 네 가지예요.

**1. 의존성이 선언한 내용을 나열하세요.** 프로젝트 루트에서요.

```bash
find node_modules -name PrivacyInfo.xcprivacy -not -path '*/example/*' \
  -exec grep -ho "NSPrivacyAccessedAPICategory[A-Za-z]*" {} + | sort | uniq -c
```

2026년 10월 15일 Solys에서 이 명령어는 매니페스트 13개와 카테고리 네 개를 찾았어요. 파일 타임스탬프, 환경설정, 부팅 후 경과 시간, 디스크 공간이에요. 나열된 카테고리는 모두 앱의 최종 매니페스트나 그걸 쓰는 프레임워크의 매니페스트에 있어야 해요.

**2. 직접 작성한 네이티브 코드를 검색하세요.** 자체 모듈, 플러그인, 위젯 같은 타깃이요. 이 코드는 어떤 SDK도 대신 선언해주지 않아요.

```bash
grep -rlE "UserDefaults|systemUptime|mach_absolute_time|creationDate|modificationDate|volumeAvailableCapacity|activeInputModes" \
  --include='*.swift' --include='*.m' --include='*.mm' modules plugins targets
```

폴더는 프로젝트에 맞게 바꾸세요. Solys에서는 이 검색으로 App Group 공유 환경설정이 드러났고, 그래서 1C8F.1 코드가 들어갔어요.

**3. 생성된 매니페스트를 읽으세요.** `npx expo prebuild -p ios`를 실행하고 `ios/<NomDeTonApp>/PrivacyInfo.xcprivacy`를 여세요. 주의하세요. 이 명령어는 `ios` 폴더를 지우고 다시 만들 수 있어요. 그 폴더를 직접 수정했다면 프로젝트 사본에서 작업하세요.

**4. 최종 빌드를 확인하세요.** 의미 있는 증거는 이것뿐이에요. expo.dev의 빌드 페이지에서 IPA를 내려받고 Mac에서 실행하세요.

```bash
unzip -q MonApp.ipa -d ipa
find ipa/Payload -name PrivacyInfo.xcprivacy
plutil -p ipa/Payload/*.app/PrivacyInfo.xcprivacy
```

두 번째 줄은 앱과 프레임워크를 포함해 내장된 매니페스트를 전부 나열해요. 세 번째 줄은 앱의 매니페스트를 보여주는데, 1단계 목록과 비교하면 돼요.

## 매니페스트와 스토어 정보가 일치해야 하는 이유

매니페스트는 혼자 존재하지 않아요. 추적이나 수집 데이터를 선언했다면 App Store 페이지와 개인정보 처리방침도 같은 내용을 말해야 해요. 셋이 어긋나면 나중에 [가이드라인 5.1.1](https://devoria.fr/ko/blog/guideline-5-1-1-app-store-rejection-fix)에 따라 사람에게 리젝될 수 있어요. 무엇을 맞춰야 하는지는 [앱 개인정보 처리방침](https://devoria.fr/ko/blog/ios-app-privacy-policy-guide)에 자세히 정리했어요.

## 문제없이 빌드 제출하기

ITMS 오류는 읽을 줄 알면 금방 고쳐요. 그다음에 오는 리젝은 좀 더 차분히 봐야 해요. 대응 방법은 [Apple에 리젝된 앱](https://devoria.fr/ko/expertise/app-rejected-by-apple) 페이지에, 흔한 사유는 [Apple이 앱을 리젝하는 이유](https://devoria.fr/ko/blog/app-store-rejection-reasons-real-cases)에 있어요.

제출 전에 점검하고 싶다면 [Apple Review Kit](https://devoria.fr/ko/kits/review-apple)에 제 체크리스트와 프로젝트를 검토하는 Claude Code 스킬을 모아뒀어요. 제출이 막혀서 사람의 눈이 필요하다면 [저와 1시간 상담을 예약하세요](https://devoria.fr/ko/coaching). 화상으로 화면을 보면서 프로젝트를 같이 살펴봐요. 첫 출시를 준비 중이라면 [무료 진단을 받아보세요](https://devoria.fr/ko/diagnostic). 단계를 순서대로 정리해주고 Apple 리젝 방지 체크리스트도 보내드려요.

## 자주 묻는 질문

### ITMS-91053 때문에 빌드 제출이 막히나요?

Apple은 2024년 5월 1일부터 App Store Connect가 이 API 사용 내역을 설명하지 않은 앱을 받지 않는다고 해요. 그런데 일부 개발자는 승인된 빌드에서 경고로 이메일을 받았어요. 어느 쪽이든 다음 빌드 전에 매니페스트를 고치세요.

### UserDefaults에는 어떤 사유 코드를 골라야 하나요?

앱이 자체 환경설정만 읽고 쓴다면 CA92.1이에요. App Group으로 위젯이나 익스텐션과 공유한다면 1C8F.1을 추가하세요. C56D.1은 서드파티 SDK 전용이니 앱 매니페스트에 넣지 마세요.

### SDK마다 매니페스트를 app.json에 옮겨 적어야 하나요?

꼭 그렇지는 않아요. 매니페스트 병합이 켜져 있으면 pod 설치 때 CocoaPods 의존성의 매니페스트가 합쳐져요. 최종 매니페스트에 빠진 카테고리만 실제 사용 방식에 맞는 사유와 함께 옮겨 적으세요.

### 위젯이나 익스텐션에도 자체 매니페스트가 필요한가요?

Apple에 따르면 이 API를 쓰는 실행 파일이 들어 있는 번들은 각자 매니페스트가 있어야 해요. 익스텐션은 자체 번들에 있는 별도의 실행 파일이라서 앱 매니페스트가 커버하지 않아요.

### 다시 빌드하지 않고 ITMS-91053을 고칠 수 있나요?

아니요. 개인정보 매니페스트는 바이너리의 일부예요. 설정을 고치고 다시 빌드한 뒤, 심사에 제출하기 전에 [TestFlight](https://devoria.fr/ko/blog/testflight-iphone-app-beta-testing)에서 테스트하세요.


## 내 프로젝트

[Apple Review Kit](https://devoria.fr/ko/kits/review-apple): 제가 쓰는 App Store 심사 체크리스트, 수정한 Apple 리젝 사례, 심사자용 메모, 앱을 검토하는 Claude Code skill 두 개. 29 €.

[iOS Kit](https://devoria.fr/ko/kits/ios): Claude Code로 iPhone 앱을 만드세요. 제 앱들의 Starter Code, 작업을 검사하는 skill, Apple Review Kit, App Store Screenshots Kit, ASO Kit 포함. 129,99 €.
