跳到正文
cccskills
免费在 GitHub 公开

usage-description-audit

Detects missing or insufficiently descriptive NS*UsageDescription keys in Info.plist that cause guaranteed App Store rejection under Guideline 5.1.1(ii).

中文简介正在准备中。当前显示原文说明。

集成工具Firebase

实测评分 未实测

查看安装方法

包含的文件(1)

  • SKILL.md9.3 KB

SKILL.md(原文)

安装前可以查看交给 AI 代理的指令内容。

Skill: Usage Description Audit

<!-- SEO: NSUsageDescription missing Info.plist permission strings privacy camera microphone location contacts photos tracking FaceID App Store rejection -->

Purpose

Detects missing or insufficiently descriptive NS*UsageDescription keys in Info.plist that cause guaranteed App Store rejection under Guideline 5.1.1(ii).

Apple Guideline

  • Primary: 5.1.1(ii) — Data Collection and Storage: Purpose Strings
  • Related: 5.1.1(i), 5.1.2
  • Reference: references/guidelines/5-legal.md

Real-World Rejection Cases

  • Case: OneSignal SDK silently added NSLocationAlwaysUsageDescription dependency, app rejected for missing key even though developer never used location Source: https://github.com/OneSignal/OneSignal-iOS-SDK/issues/490 Root cause: Third-party SDK references location APIs, requiring NSUsageDescription even if app doesn't call them directly. Note: NSLocationAlwaysUsageDescription is deprecated since iOS 11. The current required key is NSLocationAlwaysAndWhenInUseUsageDescription. Some older SDKs may still inject the deprecated key — add both keys if using Always authorization to cover all iOS versions.

  • Case: Urban Airship library caused rejection for NSLocationAlwaysUsageDescription not set by developer Source: https://github.com/urbanairship/ios-library/issues/205 Root cause: SDK dependency chain included location APIs without developer's knowledge. Always audit Pods/ and .build/ dependency trees for injected NSUsageDescription keys after adding a new SDK.

  • Case: Generic string "App needs access" rejected — reviewer flagged as insufficient justification Source: Apple Developer Forums Root cause: Purpose strings must clearly describe the specific use case, not generic access reasons

  • Case: App declared NSCameraUsageDescription in Info.plist but had no camera feature in the UI — reviewer could not find any camera usage — rejected for requesting unnecessary permission under Guideline 5.1.1(ii) Source: Apple Developer Forums (Guideline 5.1.1 threads on unnecessary permission requests) Root cause: Requesting a permission not actually used in the app violates Guideline 5.1.1(ii); remove any NS*UsageDescription key for APIs the app does not actually call

Trigger

Invoke on any iOS/macOS project before App Store submission to verify all required NS*UsageDescription keys are present and sufficiently descriptive.

Inputs

NameTypeDefaultDescription
project_rootpathcwdiOS/macOS project root
shared_contextobjectnilPre-collected context from appstore-full-audit Phase 1

Actions

Phase 1: Context Collection

Skip this phase if shared_context is provided.

  1. Glob **/Info.plist — locate the app's Info.plist file(s).
  2. Glob **/*.swift — collect Swift source files for API usage cross-reference.
  3. Glob **/*.m — collect Objective-C source files.
  4. Read the primary Info.plist to extract all NS*UsageDescription keys and their values.

Phase 2: Checks

  1. NSCameraUsageDescription Grep pattern AVCaptureDevice|AVFoundation in **/*.swift and **/*.m. If found, verify NSCameraUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  2. NSMicrophoneUsageDescription Grep pattern AVAudioSession|AVAudioEngine|AVAudioRecorder in **/*.swift and **/*.m. If found, verify NSMicrophoneUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  3. NSLocationWhenInUseUsageDescription Grep pattern CLLocationManager|requestWhenInUseAuthorization in **/*.swift and **/*.m. If found, verify NSLocationWhenInUseUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  4. NSLocationAlwaysAndWhenInUseUsageDescription Grep pattern requestAlwaysAuthorization in **/*.swift and **/*.m. If found, verify NSLocationAlwaysAndWhenInUseUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  5. NSContactsUsageDescription Grep pattern CNContactStore|Contacts.framework in **/*.swift and **/*.m. If found, verify NSContactsUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  6. NSPhotoLibraryUsageDescription Grep pattern PHPhotoLibrary|Photos.framework in **/*.swift and **/*.m. If found, verify NSPhotoLibraryUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  7. NSUserTrackingUsageDescription Grep pattern Firebase|Amplitude|Mixpanel|Segment|Branch|AppsFlyer|Adjust|ATTrackingManager in **/*.swift and project files. If any analytics/tracking SDK found, verify NSUserTrackingUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  8. NSFaceIDUsageDescription Grep pattern LAContext|LocalAuthentication|evaluatePolicy in **/*.swift and **/*.m. If found, verify NSFaceIDUsageDescription exists in Info.plist with value length > 20 characters. Missing key → 🔴 CRITICAL. Value ≤ 20 chars → 🟠 HIGH.

  9. Cross-reference requestXAuthorization calls Grep pattern requestWhenInUseAuthorization|requestAlwaysAuthorization|requestAccess|requestAuthorization|requestTrackingAuthorization in **/*.swift. For each authorization call found, confirm corresponding NS*UsageDescription key exists in Info.plist. Any mismatch → 🔴 CRITICAL.

Phase 3: Output

Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.

Output Format

## Usage Description Audit — Findings

### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO: Add NSCameraUsageDescription to Info.plist — app uses AVCaptureDevice but key is missing — Guideline 5.1.1(ii)
- [ ] TODO: Add NSUserTrackingUsageDescription to Info.plist — Firebase SDK detected but tracking purpose string absent — Guideline 5.1.1(ii)

### 🟠 HIGH — Very likely rejection
- [ ] TODO: Expand NSMicrophoneUsageDescription to > 20 characters explaining why the microphone is needed — current value is too generic — Guideline 5.1.1(ii)

### 🟡 MEDIUM — Possible rejection
- [ ] TODO: Review third-party SDK dependencies for hidden permission requirements — e.g. analytics SDKs may pull in location APIs

### 🟢 LOW — Best practice
- [ ] TODO: Audit all NS*UsageDescription strings for specificity — avoid phrases like "required for functionality"

Tools Used

Glob, Grep, Read

Constraints

  • Read-only. No file edits.
  • No network calls.
  • Skip Phase 1 if shared_context is provided by orchestrating agent.
  • Works on Swift, Objective-C, React Native, Flutter projects.

Quick Commands

Run these in your project root to check manually:

# List all NS*UsageDescription keys in Info.plist
!find . -name "Info.plist" -not -path "*/Pods/*" | head -1 | xargs plutil -convert json -o - | python3 -c "import sys,json; [print(k,'=',v) for k,v in json.load(sys.stdin).items() if 'UsageDescription' in k]"

# Find permission request calls in code
!grep -rn "requestWhenInUseAuthorization\|requestAlwaysAuthorization\|requestAccess\|requestAuthorization\|requestTrackingAuthorization" . --include="*.swift"

# Check for any NS*UsageDescription in all plist files
!grep -rn "UsageDescription" . --include="*.plist"

Swift Anti-Pattern Reference

examples/swift/PermissionPatterns.swift

Detection Steps

  1. Find target files

    • Glob: **/Info.plist, **/*.swift, **/*.m, **/Podfile.lock
  2. Search for rejection patterns

    • Read Info.plist → extract all NS*UsageDescription keys and their string values
    • Flag values shorter than 10 characters or matching App needs access\|To improve your experience\|Required
    • Grep requestAccess\|requestAuthorization\|requestWhenInUseAuthorization\|requestAlwaysAuthorization in Swift — cross-reference with Info.plist keys
    • Grep NSLocationAlwaysUsageDescription\|NSPhotoLibraryUsageDescription in Podfile.lock comments (third-party SDK additions)
  3. Determine verdict

    • Permission requested in code + corresponding NS*UsageDescription missing from Info.plist → 🔴 CRITICAL (Guideline 5.1.1(ii))
    • NS*UsageDescription value is generic (< 10 chars or matches boilerplate) → 🟠 HIGH
    • All descriptions are specific and descriptive → 🟢 pass
  4. Report

    • Missing key name and the code location requesting that permission
    • Exact value of any generic description
    • Fix: Add specific purpose strings explaining exactly what the permission enables (e.g., "To attach photos to your messages" instead of "Photo access needed")

评价

还没有评价。欢迎分享你的使用感受。

评论

无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。

还没有评论。来写第一条吧。

提交后会立即公开。请勿填写邮箱、电话等个人信息。URL 最多 2 个。

0 / 1000 字

此表单受 reCAPTCHA 保护,适用 Google 的隐私权政策和服务条款。

同一仓库的技能

Detects missing or insufficient in-app account deletion functionality required since June 30, 2022 under Guideline 5.1.1(v) for all apps that support account creation.

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects feature patterns that require a higher age rating than commonly submitted, enforcing Guideline 2.3.6 which requires age ratings to accurately reflect the app's content and social features.

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects apps that send user data to third-party AI systems without explicit in-app consent and disclosure, enforcing Guideline 5.1.2(i).

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects placeholder content, stub UI, hardcoded test credentials, and non-production endpoints that signal an incomplete app to reviewers under Guideline 2.1.

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

Detects app name violations including names exceeding 30 characters, beta labels, Apple trademark terms, and version numbers in the display name, enforcing Guideline 2.3.7.

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

App Store rejection prevention for iOS/macOS apps. Covers privacy, UGC, IAP, metadata, layout, and quality checks based on real Apple rejection cases.

中文简介正在准备中。当前显示原文说明。

cruisediary/apple-app-review-skills192026年5月2日 更新

查看 cruisediary 的全部技能

报告此技能的问题