Privacy Manifest(PrivacyInfo.xcprivacy)는 2024년 봄부터 모든 애플리케이션과 타사 SDK가 iOS 빌드에 포함해야 하는 파일입니다. Apple은 보호된 API(Required Reason API) 사용 이유와 수집되는 데이터 유형을 선언하도록 요구합니다. Apple 개발자 문서에 따르면, 애플리케이션 내의 모든 바이너리 — 메인 타겟, 프레임워크, Swift Package Manager 종속성 — 에는 자체 Privacy Manifest가 포함되어야 합니다.
핵심 요점
Privacy Manifest는 property list(XML) 형식의 PrivacyInfo.xcprivacy 파일로, 애플리케이션이 수집하는 데이터 유형과 특정 API를 사용하는 이유를 선언합니다. Apple은 Privacy Nutrition Label과 유사한 개인정보 투명성 제고 이니셔티브의 일환으로 매니페스트를 도입했지만, 코드 및 바이너리 수준에서 작동합니다.
매니페스트의 주요 목적은 소위 Required Reason API의 사용을 문서화하는 것입니다. 이는 기기의 디지털 지문 채취(fingerprinting)에 사용될 수 있는 API 카테고리이므로, 각 사용에는 Apple의 승인된 목록에서 특정 이유를 선언해야 합니다.
2024년 5월 1일부터 Apple은 Privacy Manifest가 없는 빌드를 거부합니다. 이는 애플리케이션의 메인 타겟뿐만 아니라 모든 임베디드 SDK 및 종속성에도 적용됩니다. WWDC 2023에 따르면, App Store를 통해 배포되는 모든 애플리케이션에 매니페스트가 필수입니다.
매니페스트는 모든 바이너리에 존재해야 합니다 — 메인 애플리케이션뿐만 아니라 모든 프레임워크와 정적 라이브러리에도 필요합니다. 타사 SDK가 매니페스트를 제공하지 않은 경우, 개발자가 수동으로 추가하거나 SDK 공급업체에 업데이트를 요청해야 합니다.
매니페스트 이전에는 개발자가 투명한 설명 없이 광범위한 시스템 API(파일 시스템 접근, 날짜/시간, 시스템 로그)를 사용할 수 있었습니다. 이로 인해 개발자 모르게 정보를 수집할 수 있는 타사 SDK를 통한 데이터 유출 위험이 발생했습니다.
Mysk Inc.(2023)에 따르면, 많은 인기 SDK가 명시적 필요성 없이 기기 지문 채취에 API를 사용했습니다 — 예를 들어, 시간대를 확인하기 위해 업타임을 읽거나 메타데이터 수집을 위해 디렉토리를 스캔하는 방식입니다. Privacy Manifest는 이러한 모든 작업을 선언하도록 의무화합니다.
Required Reason API 외에도, 매니페스트에는 NSPrivacyTracking 섹션 — 앱이 트래킹을 사용하는지 여부를 나타내는 플래그(ATT 필요)와 NSPrivacyCollectedDataTypes — Privacy Nutrition Label 형식의 수집된 데이터 유형 목록이 포함됩니다.
Privacy Nutrition Label은 App Store의 앱 페이지에 표시되는 사용자 대상 표현으로, 앱이 수집하는 데이터를 보여줍니다. Privacy Manifest는 바이너리 내부의 기술 파일로, Apple이 자동으로 확인합니다. 매니페스트의 데이터가 App Store Connect의 레이블과 일치하지 않으면 Apple이 빌드를 거부합니다.
따라서 매니페스트는 Apple의 검증 시스템의 신뢰 소스입니다. 개인정보 레이블은 이를 기반으로 자동 생성되지만, 개발자는 두 표현을 모두 최신 상태로 유지해야 합니다. 게시 후 매니페스트를 변경하려면 검토를 위해 새 빌드를 제출해야 합니다.
PrivacyInfo.xcprivacy 파일은 루트 유형이 Dictionary인 property list 형식을 사용합니다. 주요 최상위 키는 다음과 같습니다: NSPrivacyTracking(Boolean), NSPrivacyTrackingDomains(Array), NSPrivacyCollectedDataTypes(Array), NSPrivacyAccessedAPITypes(Array).
NSPrivacyTracking 키 — 앱이 트래킹을 적용하는지 여부를 나타내는 부울 값(ATT 필요). true인 경우 Info.plist에 NSUserTrackingUsageDescription도 지정해야 합니다. NSPrivacyTrackingDomains 키 — 트래킹이 적용되는 도메인 배열.
NSPrivacyCollectedDataTypes 키 — 각 딕셔너리가 수집된 데이터 유형을 설명하는 딕셔너리 배열: 카테고리(NSPrivacyCollectedDataType), 연결(NSPrivacyCollectedDataLinked), 목적(NSPrivacyCollectedDataTypePurposes). 목적에는 타사 광고, 분석, 제품 개발, 콘텐츠 개인화가 포함됩니다.
NSPrivacyAccessedAPITypes 키 — 각 Required Reason API 카테고리에 대한 딕셔너리 배열: 카테고리(NSPrivacyAccessedAPITypeReasons) — Apple의 승인된 목록에서 특정 이유, NSPrivacyAccessedAPIType — API 카테고리 식별자.
<!-- PrivacyInfo.xcprivacy -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPrivacyTracking</key>
<false/>
<key>NSPrivacyAccessedAPITypes</key>
<array>
<dict>
<key>NSPrivacyAccessedAPIType</key>
<string>NSPrivacyAccessedAPICategoryFileTimestamp</string>
<key>NSPrivacyAccessedAPITypeReasons</key>
<array>
<string>C617.1</string>
</array>
</dict>
</array>
</dict>
</plist>
데이터 유형은 여러 카테고리로 나뉩니다: 연락처 정보(이름, 이메일, 전화), 재정(결제 데이터), 식별자(IDFA, 사용자 ID), 사용 데이터(로그, 클릭), 진단(충돌 로그) 및 사용자 콘텐츠(사진, 비디오, 파일). 각 카테고리는 추가로 "사용자 연결" 또는 "연결 안 됨"으로 표시됩니다.
연결은 데이터가 사용자 계정에 연결됨을 의미하며, 연결 안 됨은 데이터가 집계되거나 익명화되었음을 의미합니다. 이 표시는 Apple이 개인정보 레이블을 표시하는 방식에 영향을 줍니다: 연결된 데이터는 노란색, 연결 안 된 데이터는 녹색으로 표시됩니다.
Apple은 여러 API 카테고리를 식별했으며, 각 사용에는 승인된 목록에서 특정 이유가 수반되어야 합니다. 이유는 고유 코드로, 예를 들어 C617.1 또는 35F9.1과 같이 Apple이 허용하는 특정 목적에 매핑됩니다.
NSPrivacyAccessedAPICategoryFileTimestamp 카테고리에는 파일 타임스탬프(creationDate, modificationDate)에 접근하는 API가 포함됩니다. 이유: C617.1(파일 동기화), 3B52.1(백업), 0A2A.1(사기 방지).
NSPrivacyAccessedAPICategoryDiskSpace 카테고리에는 디스크 여유 공간 확인 API가 포함됩니다(NSFileManager. 확인(NSFileManager). 이유: E174.1(캐시 관리), 85F4.1(콘텐츠 다운로드), B728.1(진단).
NSPrivacyAccessedAPICategorySystemBootTime 카테고리에는 시스템 부팅 시간(업타임) 접근 API가 포함됩니다. 이유는 하나만 있습니다: 35F9.1(분석을 위한 세션 시간 측정). 다른 모든 사용은 핑거프린팅으로 간주됩니다.
각 카테고리에는 1~5개의 승인된 이유가 있습니다. 개발자는 API의 실제 사용에 가장 정확하게 일치하는 이유를 선택해야 합니다. 부정확한 이유를 제공하면 빌드 거부 또는 계정 정지로 이어질 수 있습니다.
2024년 5월 1일부터 모든 타사 SDK(바이너리 및 오픈 소스 모두)는 패키지에 Privacy Manifest를 포함해야 합니다. Apple은 모든 종속성의 매니페스트를 확인하며, 하나라도 매니페스트가 없으면 빌드가 거부됩니다.
주요 SDK(Firebase, Adjust, AppsFlyer, Facebook SDK)는 이미 패키지를 업데이트했습니다. 프로젝트에서 잘 알려지지 않은 SDK를 사용하는 경우 버전을 확인하고 필요시 업데이트하거나 개발자에게 문의하세요. 임시 해결책으로 프로젝트에 SDK용 매니페스트를 수동으로 추가할 수 있지만, 업데이트 시 불일치가 발생할 수 있으므로 권장되지 않습니다.
Xcode 15+의 내장 템플릿을 통해 또는 수동으로 PrivacyInfo.xcprivacy를 생성할 수 있습니다. 두 옵션을 살펴보겠습니다.
Xcode 15에는 Privacy Manifest 템플릿이 포함되어 있습니다: File → New → File → Resource → Privacy Manifest. Xcode는 기본 구조의 파일을 생성하고 NSPrivacyTracking 및 API와 데이터용 빈 배열을 채웁니다. 생성 후 각 사용된 Required Reason API에 대한 이유를 수동으로 지정해야 합니다.
템플릿은 자동으로 파일을 메인 타겟에 추가합니다. 프로젝트에 여러 타겟이 있는 경우(Extensions, Watch app), 각 타겟에 매니페스트를 추가해야 합니다. Xcode는 컴파일 시 종속성의 매니페스트 존재를 확인하지 않으며 — 아카이브 단계에서만 확인합니다.
// AppDelegate: 개발 단계에서 매니페스트 확인
import Foundation
func validatePrivacyManifest() {
guard let path = Bundle.main.path(
forResource: "PrivacyInfo", ofType: "xcprivacy"
) else {
print("PrivacyInfo.xcprivacy를 찾을 수 없음")
return
}
guard let dict = NSDictionary(contentsOfFile: path)
else { return }
print("Privacy manifest loaded: \(dict.count) keys")
}
PrivacyInfo.xcprivacy를 일반 XML property list 파일로 수동 생성할 수 있습니다. 이렇게 하려면 PrivacyInfo.xcprivacy라는 파일을 만들고 표준 plist 헤더를 작성한 후 필요한 키가 있는 루트 딕셔너리를 추가합니다. 파일이 타겟에 추가되었는지 확인하세요(Target Membership).
수동 방법은 Xcode UI를 사용하지 않고 정적 라이브러리나 Package Manager 종속성에 매니페스트를 추가해야 할 때 유용합니다. 컴파일 후 nm 명령어나 아카이브를 통해 파일이 바이너리에 포함되었는지 확인합니다.
App Store에 빌드를 제출하기 전에 Privacy Manifest가 정확하고 완전한지 확인해야 합니다. Apple은 여러 검증 도구를 제공합니다.
프로젝트를 아카이브할 때(Product → Archive), Xcode는 매니페스트 검증을 수행합니다. 오류가 발견되면 — 매니페스트 누락, 잘못된 이유, 빈 카테고리 — 아카이브가 오류와 함께 실패합니다. 오류 로그는 Issue 내비게이터에 표시되며 문제가 있는 SDK와 API 카테고리를 나타냅니다.
빌드 업로드 시 App Store Connect 측에서 추가 검증이 수행됩니다. 검증에 실패하면 문제가 있는 API의 식별자와 권장 수정 사항이 포함된 자동 이메일과 함께 빌드가 거부됩니다.
검증을 자동화하려면 Required Reason API 사용에 대해 바이너리를 분석하는 스크립트를 사용하세요. Apple은 libtool 도구와 심볼 검증 스크립트를 제공하지만, 커뮤니티에서 더 편리한 유틸리티를 개발했습니다.
# 바이너리에서 FileTimestamp API 사용 검색
nm MyApp.app/MyApp | grep "NSFileCreationDate"
# 애플리케이션에서 PrivacyInfo.xcprivacy 존재 확인
find MyApp.app -name "*.xcprivacy"
가장 흔한 오류는 SDK 중 하나에 매니페스트가 없는 것입니다. 메인 타겟에 매니페스트가 있어도 Apple은 각 바이너리를 개별적으로 확인합니다. 두 번째로 흔한 오류는 잘못된 이유 코드입니다 — 한 API 카테고리의 이유를 다른 카테고리의 API와 함께 사용하는 경우입니다.
세 번째 오류는 실제로 사용되지 않는 API의 과도한 선언입니다. 개발자가 "만일을 대비해" 모든 가능한 이유를 추가하면 Apple 검토자에게 의심을 받게 됩니다. 실제로 사용되는 카테고리만 추가하세요. 확인에는 Xcode 정적 분석기를 사용하세요.
자주 묻는 질문
2024년 5월 1일부터 Apple은 매니페스트가 없는 모든 빌드를 거부합니다. 오류는 App Store Connect에 업로드하는 단계에서 발생합니다. 오래된 애플리케이션은 차단되지 않지만, 업데이트에는 매니페스트의 필수 포함이 필요합니다.
네, 매니페스트는 모든 Apple 플랫폼에 필수입니다: iOS, iPadOS, macOS, tvOS, watchOS 및 visionOS. Required Reason API 요구 사항은 모든 플랫폼에서 동일하지만, API 세트는 약간 다를 수 있습니다.
SDK가 매니페스트를 제공하지 않은 경우 별도의 PrivacyInfo.xcprivacy 파일을 생성하여 프로젝트의 SDK 그룹에 추가하세요. SDK의 문서를 기반으로 이 SDK가 사용하는 API에 대한 이유를 지정합니다.
네. 자동 확인 중 Apple은 선언된 이유를 실제 API 호출과 비교합니다. 불일치는 거부로 이어집니다. 수동 검토 중 검토자가 설명을 요청할 수 있습니다.
네, Apple은 SPM을 포함한 모든 종속성의 매니페스트를 확인합니다. 패키지 제공자는 저장소에 PrivacyInfo.xcprivacy를 포함해야 합니다. Xcode는 아카이브 시 누락된 매니페스트에 대해 경고합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.