Skip to content

ITMS-90683: Missing purpose string in Info.plist ​

You uploaded a build, and minutes later Apple emailed you this:

ITMS-90683: Missing purpose string in Info.plist — Your app's code
references one or more APIs that access sensitive user data. The app's
Info.plist file should contain a NSCameraUsageDescription key with a
user-facing purpose string explaining clearly and completely why your
app needs the data.

The build is rejected before it ever reaches a human reviewer. Here is what causes it and how to fix it properly.

What the error actually means ​

iOS gates a set of APIs behind user consent — camera, microphone, photos, location, contacts, calendar, motion, tracking. Before the system shows the permission prompt, it needs a sentence to display: why does this app want your camera?

That sentence lives in your Info.plist, under a key specific to each permission. If your binary references a gated API and the matching key is absent, Apple's static analyzer catches it at upload time and returns ITMS-90683.

Two things follow from this being a static check:

  • It fires on the API being referenced, not called. Dead code, a commented-out feature you left in, or a helper you never wired up will still trigger it.
  • It fires on code inside your dependencies too. A SDK that touches PHPhotoLibrary makes the key your responsibility, not theirs.

If you ship without the key and Apple's analyzer somehow misses it, the app doesn't merely get rejected — it crashes the moment the API is called. The purpose string is not paperwork; it's a runtime requirement.

The key for each API ​

API you referenceInfo.plist key required
AVCaptureDevice, AVCaptureSessionNSCameraUsageDescription
AVAudioRecorder, requestRecordPermission, AVAudioApplicationNSMicrophoneUsageDescription
PHPhotoLibrary, PHPickerViewController, UIImagePickerControllerNSPhotoLibraryUsageDescription
CLLocationManagerNSLocationWhenInUseUsageDescription
CNContactStoreNSContactsUsageDescription
ATTrackingManagerNSUserTrackingUsageDescription
EKEventStoreNSCalendarsUsageDescription
CMMotionManagerNSMotionUsageDescription

Fixing it ​

Add the key to your target's Info.plist:

xml
<key>NSCameraUsageDescription</key>
<string>Scan a document to attach it to a report.</string>

Then bump the build number and re-upload. There is no way to fix this server-side — the check runs against the binary, so it needs a new binary.

Write a string that survives review ​

Apple rejects purpose strings that don't explain anything. These get sent back under guideline 5.1.1:

RejectedWhy
Camera accessRestates the permission, explains no purpose.
This app needs the camera.Same. "Needs" is not a reason.
Required for full functionalityVague, and reviewers read it as evasive.

What passes is a concrete user-facing benefit, in the user's language:

Accepted
Scan a receipt to add it to an expense.
Record a voice note to attach to a task.
Show nearby stations on the map.

Two practical notes:

  • The string is localized. Put it in InfoPlist.strings for each language you ship, not just the base one. A French user seeing an English purpose string is a poor first impression, and reviewers testing in another locale have flagged it.
  • Keep it to one sentence. The system prompt truncates long strings.

Finding what triggered it ​

Apple's email names the key, not the code. If you don't know why your app references the API, search the whole project — including packages:

sh
grep -rn "AVCaptureDevice\|AVCaptureSession" --include="*.swift" .

If nothing turns up in your own sources, it came from a dependency. Check your Swift packages and any embedded frameworks. You still have to declare the key.

Catching it before you upload ​

The upload-reject-fix-reupload loop costs 20 minutes each time — archive, upload, wait for processing, read the email, fix, repeat. The check itself is mechanical: cross-reference the privacy APIs in your sources against the keys in your Info.plist.

That's what AuditStore does locally. Its usage-strings check parses your sources and your Info.plist and reports any gated API missing its key as Blocking, before you archive. No upload, no waiting.

AuditStore is a macOS app by NativLab. Runs entirely on your Mac — your API private key never leaves your device.