Do it yourself
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
See plans on the main pageApp Store Connect error
ITMS-90683 arrives by email shortly after an upload: your binary references a protected resource such as the camera, location or contacts, and Info.plist has no sentence explaining why. Add the named key with one honest sentence and upload a new build. The part worth getting right is the sentence itself, because App Review reads it too.
From $109 one-time per platform, or let our team do it all from $698.
The message names a key, for example NSCameraUsageDescription or NSLocationWhenInUseUsageDescription, and the bundle it is missing from. Apple's wording also points out that external libraries and SDKs may reference these APIs, and that a purpose string is required even if your app might not use them. Treat it as blocking: fix the key, raise the build number and upload again.
Your web app asks for the camera through <input type="file" capture>, for location through navigator.geolocation and for the microphone through getUserMedia. Inside a WebViewGold app all of these go through WebKit and the native shell, and iOS uses the purpose strings from the app's Info.plist for the permission dialog. Without the string, iOS cannot show the dialog and terminates the app instead, which is exactly what Apple's upload check prevents.
The most common trigger in WebViewGold projects is the cleanup that Guideline 2.5.1 encourages: you delete purpose strings for features you do not use, and one of them belongs to code that is still compiled into the binary. The email is the authority on what the binary references, so the key goes back in, with a precise sentence.
Xcode shows the readable name in the Info.plist editor; the email uses the raw key.
| Raw key in the email | Shown in Xcode as | Your app needs it when it... |
|---|---|---|
NSCameraUsageDescription | Privacy - Camera Usage Description | takes photos or video for uploads, uses qrcode:// or barcodescanner://, the document scanner (kVisionKitEnable), the flashlight API, or a camera stream in the web app. See QR scanner docs. |
NSPhotoLibraryAddUsageDescription | Privacy - Photo Library Additions Usage Description | saves images with savethisimage://?url= or screenshots with takescreenshot:// (file downloader docs). |
NSPhotoLibraryUsageDescription | Privacy - Photo Library Usage Description | reads from the photo library, for example for image uploads, or when the email asks for it. |
NSMicrophoneUsageDescription | Privacy - Microphone Usage Description | records audio: voice notes, speech input in an AI chat, or video with sound. |
NSLocationWhenInUseUsageDescription | Privacy - Location When In Use Usage Description | calls the HTML5 geolocation API (HTTPS only, see geolocation docs). |
NSLocationAlwaysAndWhenInUseUsageDescription | Privacy - Location Always and When In Use Usage Description | sets backgroundlocation to true for location in the background. |
NSContactsUsageDescription | Privacy - Contacts Usage Description | uses requestcontactpermission:// and readcontacts://. |
NSFaceIDUsageDescription | Privacy - Face ID Usage Description | uses enableBioMetricAuth or bioauth:// (biometric docs). |
NFCReaderUsageDescription | Privacy - NFC Scan Usage Description | uses the NFC plugin (readnfc://, writenfc://). |
NSHealthShareUsageDescription and NSHealthUpdateUsageDescription | Privacy - Health Share / Health Update Usage Description | uses the HealthKit plugin (readhealthkit://, writehealthkit://). Both keys are required by the HealthKit docs. |
NSUserTrackingUsageDescription | Privacy - Tracking Usage Description | always. The WebViewGold docs state this key is required and that removing it makes the app crash. |
Apple's purpose string guidance asks for one complete sentence in active voice that names the feature and what happens with the data. No marketing, no restating the resource name.
| Resource | Gets questioned | Passes |
|---|---|---|
| Camera | This app needs camera access. | Scan the QR code on your membership card to check in at the front desk. |
| Location | To use location. | Shows the climbing gyms closest to you and the walking time to each one. |
| Photo additions | Save photos. | Saves your event ticket to Photos so you can show it at the entrance without a connection. |
| Microphone | Microphone required for the app. | Records your voice note and turns it into text for your journal entry. |
| Face ID | Use Face ID. | Unlocks your budget with Face ID instead of your password. |
| Contacts | Access your contacts for a better experience. | Lets you pick friends from your contacts to invite to a shared list. Only the people you select are sent to our server. (Write the second sentence only if it is true.) |

Great work! Never coded anything but managed to work with this. Easy and fast! Also with great help from the creators!
The bundle can be your main app or an extension target (push service extension, widget, share extension, App Clip). Each target has its own Info.plist, and the key has to be in the one the email names.
Open that Info.plist, hover over a row, click the plus, choose the "Privacy - ..." entry from the list and paste your sentence. Or right-click the file, choose Open As, Source Code, and add the key and string pair shown below.
If the feature is part of your app, describe it. If it is not, there are two honest options: add the key with an accurate sentence about what that code does (the ITMS email itself says a string is required even if your app might not use the API), or remove the code that references the API, which Apple's purpose string guidance recommends when there is no valid reason. In a WebViewGold project, do not delete Swift files or SDKs on your own (the docs warn that removing the AdMob SDK causes many dependency errors); ask support about removing a module instead. A purpose string never shows a dialog on its own; iOS displays it only when code actually requests access.
Add the same keys to InfoPlist.strings for each language your app supports, and keep the English string in Info.plist as the fallback. Test each language on a device.
Archive, upload, and wait for the processing email. If processing finishes without an ITMS email, the build appears in TestFlight.
Install the TestFlight build, use each feature that asks for permission, and check that the dialog appears at the moment of use with your sentence. A dialog at first launch with no visible reason is what reviewers flag under 5.1.1.
Example values; replace them with sentences about your own features.
<key>NSCameraUsageDescription</key>
<string>Scan the QR code on your membership card to check in at the front desk.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Saves your event ticket to Photos so you can show it at the entrance without a connection.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Shows the climbing gyms closest to you and the walking time to each one.</string>
<key>NSFaceIDUsageDescription</key>
<string>Unlocks your budget with Face ID instead of your password.</string>My upload was refused with ITMS-90683 (email below). In this WebViewGold iOS project: 1. Tell me which target and which Info.plist each missing key belongs to. 2. Read Config.swift and list which native features are enabled (scanners, document scanner, geolocation, background location, biometrics, contacts, NFC, HealthKit, file and image saving). 3. Add each missing key to the correct Info.plist. Write the value as one complete sentence in active voice that names the concrete feature in my app and what happens with the data. No marketing words, no "to provide a better experience". My app: [one paragraph about what the app does and for whom]. 4. If a key belongs to a feature that is not enabled, still add it, write an accurate sentence for what that code does, and list it separately so I can decide. 5. If InfoPlist.strings files exist, add translations for each key in those languages. 6. Never remove NSUserTrackingUsageDescription. Do not change any other file. Email: [paste the ITMS-90683 email here]
Because code in your binary, often an SDK or a template module, references the camera API. Apple's check looks at the binary, not at which features you switched on. Add the key with an accurate sentence, or have the code removed.
No. The dialog appears only when code actually requests access, for example when a user taps your scan button. A string for an unused feature is never shown.
Write the Info.plist value in the app's main language and add InfoPlist.strings files for other languages your app supports. The Info.plist value is the fallback for every language you did not translate.
It can. A sentence like "This app needs your location" is a typical Guideline 5.1.1 finding. Name the feature and the benefit in one concrete sentence.
You need a new build. Info.plist is part of the app bundle, so the fix only reaches Apple with a new upload and a higher build number.
Same result, different amount of work on your side. All three come with the approval guarantee and 24/7 human support.
$109 per platform, one-time
The WebViewGold license: a finished Xcode or Android Studio project. Paste your URL, set name and icon, switch on features, build and submit. Free updates forever.
See plans on the main page$349 per license, one-time add-on
No Mac, no Xcode, no Android Studio: configure in the browser, we build both apps in the cloud and hand them to App Store Connect and the Play Console.
How the Cloud Builder works Try the free demo$698 per platform $798
Send us your URL and icon. Our team configures, builds and delivers your app within 72 hours, white-label, with source projects. Both platforms for $1,158.
Full Service details Powered byWinter Sale prices valid until December 31, 2026.
App Store & Google Play approval guarantee – or your money back within 14 days
Rather hand it over? Full Service: we configure, build and deliver within 72 hours, from $698 per platform. Questions? Chat with us 24/7.
Refunds are granted under the conditions listed in our FAQ: a non-content rejection by Apple and/or Google, claimed within 14 days after purchase.