- New: review-rejections, portfolio-originality, release-management, store-preflight, privacy-manifest, export-compliance, aso-basics, whats-new - Updated: explicit build numbers, first availability UI fallback, phased + manual release by default, IAP versions in review submissions (API 4.4.1, reported, verify), IAP description 45, privacy manifest cross-links, tool-neutral CLI instructions - docs/agents-core.md: shared rules for every agent
42 lines
3.4 KiB
Markdown
42 lines
3.4 KiB
Markdown
---
|
|
name: privacy-manifest
|
|
description: Add and check Apple privacy manifests (PrivacyInfo.xcprivacy) for an iOS game - required-reason API categories (UserDefaults, file timestamps, system boot time, disk space, active keyboards) with approved reason codes, tracking flag and domains, collected data types, and third-party SDK manifests (ad networks, analytics, Firebase, Unity, Capacitor plugins). Use when App Store Connect sends ITMS-91053 "Missing API declaration" or ITMS-91061 "Missing privacy manifest", or before submitting an iOS build.
|
|
---
|
|
|
|
# Privacy manifest (iOS)
|
|
|
|
Scan: `storebound privacy-manifest --ios ios/App` (local, no credentials). Capacitor / Cordova plugins live outside
|
|
the iOS folder: add `--sdk-dirs node_modules/@capacitor,node_modules/<plugin>`. Exit 1 when something blocks upload.
|
|
|
|
## What Apple checks at upload
|
|
- **ITMS-91053 Missing API declaration**: the binary uses a required-reason API and no manifest in the app or in the
|
|
SDK that calls it declares the category with a reason.
|
|
- **ITMS-91061 Missing privacy manifest**: an SDK from Apple's list of commonly used SDKs (Firebase, Google utilities,
|
|
Alamofire, OneSignal, Unity framework, Capacitor, Flutter ...) is linked without its own manifest (and signature for
|
|
binary SDKs). Fix by updating the SDK, not by declaring it in your app's manifest.
|
|
|
|
## Steps
|
|
1. Xcode > File > New > File > App Privacy (PrivacyInfo.xcprivacy), target = the app.
|
|
2. Run the scan. For each used category add `NSPrivacyAccessedAPITypes` > item with `NSPrivacyAccessedAPIType` and
|
|
`NSPrivacyAccessedAPITypeReasons`. Typical for games:
|
|
- `NSPrivacyAccessedAPICategoryUserDefaults` + `CA92.1` (settings / saves read and written by the app itself;
|
|
Capacitor Preferences and most engines use UserDefaults)
|
|
- `NSPrivacyAccessedAPICategoryFileTimestamp` + `C617.1` (timestamps of files in the app container)
|
|
- `NSPrivacyAccessedAPICategorySystemBootTime` + `35F9.1` (elapsed time between events)
|
|
- `NSPrivacyAccessedAPICategoryDiskSpace` + `E174.1` (check space before writing)
|
|
Pick the reason that is true; read Apple's reason list ("Describing use of required reason API") if unsure.
|
|
3. Tracking: `NSPrivacyTracking` true only if the game tracks (ad SDK with IDFA after ATT); then list
|
|
`NSPrivacyTrackingDomains` the SDK docs name. Keep it consistent with App Privacy "used for tracking" and the ATT
|
|
prompt (`store-declarations`).
|
|
4. `NSPrivacyCollectedDataTypes`: what the app itself collects; SDK manifests cover their own collection. Xcode's
|
|
Privacy Report (Product > Archive > Generate Privacy Report) merges all manifests; compare it with App Privacy.
|
|
5. SDKs flagged "ships no PrivacyInfo.xcprivacy": update to a version that has one (ad networks and mediation
|
|
adapters added manifests in 2024 releases; see `ads-levelplay-checks` for adapter / SDK version pairs).
|
|
6. Re-run the scan, archive, upload; Apple's email lists any remaining ITMS-910xx issue per framework.
|
|
|
|
## Gotchas
|
|
- The scan is a text search: it can miss calls inside binary frameworks (their manifest must cover them) and flag a
|
|
harmless symbol name; confirm before adding a category you do not use.
|
|
- A manifest must be in the **app target's** Copy Bundle Resources, not only in the project.
|
|
- Static libraries cannot carry a manifest bundle by themselves; the vendor ships a resource bundle or you merge their
|
|
declarations into the app's manifest as their docs say.
|