Define the security boundary
Explain privacy-sensitive access
Add accurate usage descriptions and request protected resources only when the user activates the feature that needs them.
12 minute lesson
macOS guards a set of resources it considers privacy-sensitive: camera, microphone, location, contacts, calendars, screen recording, and more. Your app can’t touch them silently. The first access triggers a system permission prompt, and the user decides.
Your part of that prompt is the purpose string: an entry in Info.plist that explains why you’re asking. If our Notes app records voice memos, it needs one for the microphone:
<key>NSMicrophoneUsageDescription</key>
<string>Notes records audio when you attach a voice memo to a note.</string>
Write it like that: name the visible feature, say what happens with the data. “App needs microphone access” tells the user nothing and earns you denials.
The purpose string is not optional. If your code touches a protected resource and the matching key is missing, macOS kills the app on the spot. The crash report says the app accessed privacy-sensitive data without a usage description. That one is confusing the first time you hit it, because everything worked until the exact line that touched the microphone.
Timing matters as much as wording. Ask in context: request microphone access when the user taps record for the first time, not at launch next to three other prompts. A request tied to a visible action gets approved far more often.
Then test the paths developers skip. First request. Denial — the app must keep working with the feature disabled gracefully, and point the user to System Settings if they change their mind. Re-test the first-run experience by resetting the permission:
tccutil reset Microphone com.flaviocopes.Notes
Never loop the prompt or treat a denial as an error to retry. The user answered. Respect it.
Lesson completed