I am developing a Flutter app and submitting it to App Store Connect and instantly get an email that the App was rejected because of
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 NSContactsUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting Spring 2019, all apps submitted to the App Store that access user data are required to include a purpose string. If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs. Learn more (https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
Supposedly there are 5 purpose strings missing.
It's right that my App is using the APIs listed in the email but I have the keys in my Info.plist file and when running the app on my iPhone the purpose strings are shown when the app requests the corresponging permissions from the user. I even translated the strings using InfoPlist.strings files in the folders en.lproj etc. In the Info.plist I referenced the translated string like this
<key>NSContactsUsageDescription</key>
<string>$(NSContactsUsageDescription)</string>
I already tried unpacking the .xcarchive (in Mac Finder right click -> Show Package Contents) and the .ipa files. In those I found the Runner.app (I think Runner is a Flutter specific "name") and also showed package contents. I found the Info.plist and when I open it in a TextEditor or also XCode the Strings are gone but the InfoPlist.strings files are still there.
I think that something goes wrong when exporting so that the values are cleared?
I actually asked the question to answer it myself hoping that it might help somebody because it took me a hell lot of time to figure out the problem, even though the solution is so easy:
I don't know from which tutorial / Stackoverflow answer or wherever else I had the trick with referencing the translations as a variable as shown in the question.
<key>NSContactsUsageDescription</key>
<string>$(NSContactsUsageDescription)</string>
Just replace the variable with a real purpose string (your app's primary language maybe? I just copy pasted the values from the English string file.)
<key>NSContactsUsageDescription</key>
<string>The reason for access to contacts is…</string>
It seems that those variables are evaluated at build time and not (also) runtime. Because they don't exist, Xcode places an empty string in the Info.plist file. During runtime the InfoPlist.strings files are searched for values overwriting those in Info.plist and therefore the internationalisation did work even though it was actually implemented incorrectly. It seems that for submission to the AppStore it is not enough to have the values in .strings files but there must be a fallback purpose string in Info.plist
A reference from Apple about localising Info.plist can be found here.
Attached is what I get from Apple after uploading to the App Store Connect, even though all of these are included in my info.plist. I have tried nearly 10 times to change the name of my string ranging from long strings (e.g. We get the bluetooth in order to connect with certain DJI models that require bluetooth to get telemetry and other data from the drone.) to short strings (e.g. We display the user's location on Mapview.)
All other questions I have seen claim the simple solution is to include the string, which I'm already doing! Does this have something to do with DJI's sdk? I would think just including this in MY info.plist would be enough. The main issue seems to be with the bluetooth permissions as another app I am trying to upload returns the same issue.
"Dear Developer,
We identified one or more issues with a recent delivery for your app,
"DJI Swift Demo". Please correct the following issues, then upload
again.
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 NSBluetoothPeripheralUsageDescription key with a
user-facing purpose string explaining clearly and completely why your
app needs the data. Starting Spring 2019, all apps submitted to the
App Store that access user data will be required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy).
Though you are not required to fix the following issues, we wanted to
make you aware of them:
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 NSLocationWhenInUseUsageDescription key with a
user-facing purpose string explaining clearly and completely why your
app needs the data. Starting Spring 2019, all apps submitted to the
App Store that access user data will be required to include a purpose
string. If you're using external libraries or SDKs, they may reference
APIs that require a purpose string. While your app might not use these
APIs, a purpose string is still required. You can contact the
developer of the library or SDK and request they release a version of
their code that doesn't contain the APIs. Learn more
(https://developer.apple.com/documentation/uikit/core_app/protecting_the_user_s_privacy)."
Instead of verifying the plist information in XCode, please look into the plist inside ipa.
Please follow the below steps to verify plist inside ipa.
Let say, your ipa file is Demo.ipa
Copy the Demo.ipa to DemoBkup.ipa
Rename it to DemoBkup.zip
Extract the zip file. (Double click the zip file)
The Extracted file will contain "Payload" folder.Get into Payload folder.
You will find the Demo package. Right click and tap "Show Package contents"
Search for your Info.plist.
Validate all the information you gave in XCode is present in this plist.
Change your info.plist keys with the keys Privacy - Bluetooth Peripheral Usage Description, Privacy - Location When In Use Usage Description. Check the given screenshot for reference:
Do check the plist file referenced by the scheme you are building. I think the plist file you are making change is not the same referenced by the scheme from what you are building the ipa file to submit to App Store.
I've submitted my app for review to the App Store Connect. Although the app is still under review, I've received an email to inform me that I have to fix an error. Here is the content of the message:
Dear Developer,
We identified one or more issues with a recent delivery for your app
XXXXX. Your delivery was successful, but you may wish to correct the
following issues in your next delivery:
"Missing Purpose String in Info.plist File. Your app's code
references one or more APIs that access sensitive user data. The
app's Info.plist file should contain a
NSLocationAlwaysUsageDescription key with a user-facing purpose
string explaining clearly and completely why your app needs the data.
Starting spring 2019, all apps submitted to the App Store that access
user data will be required to include a purpose string.If you're
using external libraries or SDKs, they may reference APIs that
require a purpose string. While your app might not use these APIs, a
purpose string is still required. You can contact the developer of
the library or SDK and request they release a version of their code
that doesn't contain the APIs.
After you’ve corrected the issues, you can use Xcode or Application
Loader to upload a new binary to iTunes Connect.
Best regards,
The App Store Team
My app is fully built with Expo and I don't know how to access and modify the Info.plist.
Any idea?
EDIT April 2019 : You now have to add these two keys, as spring 2019 has begun. Note that NSLocationAlwaysUsageDescription is now deprecated (since iOS 11) and has been replaced with NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription. If you want to support lower than iOS 11, you'll have to use the three values.
To sum up you have to:
Add NSLocationAlwaysAndWhenInUseUsageDescription AND NSLocationWhenInUseUsageDescription for iOS 11 and more
And add NSLocationAlwaysUsageDescription if you want to support iOS 10 and less
And finally, you can add NSLocationUsageDescription if you wan to support iOS 8 and less.
You can submit your app even if you got this message !
I’ve just faced the same issue yesterday, even if the app isn’t using the location functionality. It may be related to some framework included in the project that have this optional feature.
I can confirm that my app has been approved even without the NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription key in info.plist
Indeed, as Apple stated in the mail :
Starting spring 2019, all apps submitted to the App Store
that access user data will be required to include a purpose
string.
So the only thing to do is to add this key (right now is better, so that you won’t forget) in you project so that it will be included in your next update.
Just add two new entries in your info.plist, with NSLocationAlwaysUsageDescription and NSLocationWhenInUseUsageDescription as keys and a short description of why you use them as the value (even if you don’t really use them...).
If you're using Expo, you can add solve by adding infoPlist to app.json like so:
"expo": {
"ios": {
"bundleIdentifier": "com.app.myapp",
"infoPlist": {
"NSLocationAlwaysUsageDescription": "Some message to appease Apple.",
},
},
}
Expo Docs
I have some apps in the store and I tried to distribute a version for QA and the same thing happened in two different Apps.
I think this is a new criteria to accept the builds uploads to Appstore connect.
The solution is simple, add the following lines in the .plist file.
<key>NSLocationAlwaysUsageDescription</key>
<string>custom message</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>custom message</string>
PS: In my case have not using any feature of location, but I added these lines in order to comply with Appstore connect guidelines. Btw after receive that email, I could test the app even when they said that build it had some issues.
I hope this work for you guys.
It's a new requirement from apple, even if you do not use location. If you want to add the permissions in Xcode, look for "Privacy - Location Usage Description" and "Privacy - Location When In Use Usage Description" and type a custom string for each of them.
For more simplifying you can add these lines in your info.plist. These error are coming because Starting spring 2019, all apps submitted to the App Store that access user data will be required to include a purpose string.
Open info.plist as source code.
Add these following lines in your plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
##Use this key in info.plist file
NSLocationAlwaysUsageDescription
Your location is required for xyz benefits for you NSLocationWhenInUseUsageDescription
Your location is required for xyz benefits for you
"Missing Purpose String in Info.plist File. Your app's code references one or more APIs that access sensitive user data. The app's Info.plist file should contain a NSLocationAlwaysUsageDescription key with a user-facing purpose string explaining clearly and completely why your app needs the data. Starting spring 2019, all apps submitted to the App Store that access user data will be required to include a purpose string.If you're using external libraries or SDKs, they may reference APIs that require a purpose string. While your app might not use these APIs, a purpose string is still required. You can contact the developer of the library or SDK and request they release a version of their code that doesn't contain the APIs.
Open Info.plist as source code.
Add these following lines in your plist
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>$(PRODUCT_NAME) needs Location access for "some reason"!</string>
We did receive the same email and we aren't using the CoreLocation at all. After a quick search, we found that Parse SDK could use CoreLocation. In Apple's email, they clearly say:
If you're using external libraries or SDKs, they may reference APIs that require a purpose string.
That mean the minute your code or any other Library or SDKs can use CoreLocation, even if you don't use it, you need to provide privacy description for "When In Use" and "Always Use".
It is also something new from Apple and for now it's only a warning but it will be required starting in Spring 2019 for new submissions.
There are the following cases:
NSLocationAlwaysAndWhenInUseUsageDescription (iOS>11)
NSLocationWhenInUseUsageDescription (iOS>11)
NSLocationAlwaysUsageDescription (iOS<=10)
NSLocationUsageDescription (seems very old, iOS8?)
Apple states at:
Add the NSLocationWhenInUseUsageDescription key and the NSLocationAlwaysAndWhenInUseUsageDescription key to your Info.plist file.
and:
If your app supports iOS 10 and earlier, add the NSLocationAlwaysUsage
NSLocationUsageDescription seems dead, the only ref in ADC site is:
https://developer.apple.com/ibeacon/Getting-Started-with-iBeacon.pdf
So to be sure, use first 3.
This issue is occurring because you haven't included
<NSLocationAlwaysUsageDescription>
for your app. I faced the same issue when I tried to submit my app on the AppStore. After the app was processed, I got the same mail. I just added the description and now its resolved.
Hope this helps.
These answers all tell you how to comply with the App Store rules to avoid the warning but the true fix would be for Expo to allow you to disable their SDKs requirement for Location Services unless you actually use them - I'm not sure if this is possible.
Please review the email you received from **App Store Connect **
Identify The Missing Key
Instructions
Open info.plist file.
Add and search for the missing key from the options provided (e.g. Contacts = Privacy - Contacts Usage Description)
Add Usage Description:
$(PRODUCT_NAME) needs Contacts access to "Provide The Reason Here".
Example:
same issue in Feb 19, got an email with a bunch of permissions I am not using, I assume they are from plugins. Apple says in March 19 it is a requirement so I am adding these in info.plst and uploading again.
It is very silly indeed.
I had
<key>NSLocationWhenInUseUsageDescription </key>
instead of
<key>NSLocationWhenInUseUsageDescription</key>
be sure to remove trailing whitespace
I also face the same issue but after 27 hours, I received the email about approved even I did nothing. So wait for approximately 24 hours instead of doing all this process again.
With Xcode 11 copy the key NSLocationAlwaysUsageDescription and add this to Info -> Custom iOS Target Properties -> Click + in the bottom left of this tab and as a value insert some kind of description like This app requires location access to function properly..
My app also got that, and I do nothing about it but it can run well ,next time I think should add such key in plist,just do some description
A short answer to the above problem -
NSLocationAlwaysUsageDescription must be updated with the following description in Info.plist file
{Your App Name} requires access to the location to suggest dengue
outbreak zones.
In our case, we were using NSLocationWhenInUseUsageDescription in our app, but not NSLocationAlwaysUsageDescription.
Reading from the comments here (thanks matt-oakes), it looks like NSLocationAlwaysUsageDescription is being used by one of the dependency frameworks we use.
Running our app it doesn't show the actual NSLocationAlwaysUsageDescription permission modal, so it looks to just handle this in the background.
So in summary, adding NSLocationAlwaysUsageDescription to the Info.plist fixed the warning email, and did not change any behaviour in the app 👍🏻
I tried to upload my app on iTunes Connect, but the following error appeared :
Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
It worked until now. I didn't add new library.
My research conclude on modules which are :
- Take photo (no videos), but no update from 2 years
- AVAudioSession library, but no update from 3 years, and doesn't use the requestRecordPermission
And I don't use Instabug or iMessage.
I don't need microphone on my app, how I can tell I really don't use it ?
Or how I can find the library which requires the NSMicrophoneUsageDescription key ?
(I don't want to add the key to my info-plist, I think it's not normal to ask the user for something I don't use/want to use)
During submission your binary is scanned for the presence of the symbol - AVAudioSession requestRecordPermission: in this case.
when found you get an error like the one above.
You can either
just add the key as there is no prompt for your users until you actually request the permission to use the microphone.
find which of your framework is containing the symbol (you can search recursively in your build folder framework binaries with tools like strings or nm or otool, grep the above symbol and when found remove the framework from your app).
General Query
Does precise documentation exist for which API methods/properties require privacy "purpose strings" in iOS 10?
Specific Query
I have an app that links against the CoreBluetooth framework that accesses only the following methods/properties:
CBCentralManager:
state
- retrieveConnectedPeripheralsWithServices:
CBPeripheral:
name
In the documentation, I have found the following vague statements (emphases mine):
An iOS app linked on or after iOS 10.0 must include in its Info.plist file the usage description keys for the types of data it needs to access or it will crash. To access Bluetooth peripheral data specifically, it must include NSBluetoothPeripheralUsageDescription.
[...]
When the system prompts the user to allow usage, the value that you provide for this key is displayed as part of the alert.
[...]
To protect user privacy, an iOS app linked on or after iOS 10.0, and which accesses the Bluetooth interface, must statically declare the intent to do so. Include the NSBluetoothPeripheralUsageDescription key in your app’s Info.plist file and provide a purpose string for this key. If your app attempts to access the Bluetooth interface without a corresponding purpose string, your app exits.
[...]
The data and features that require user permission are described in Table 1-2.
(Table 1.2 states that NSBluetoothPeripheralUsageDescription is required to access "Bluetooth peripherals")
My app does not currently exit when it calls the APIs listed. Neither does it "prompt the user to allow usage".
However, this blog post suggests that the lack of a crash does not indicate that no purpose string is required.
(Despite the fact that my app is not "linked on or after iOS 10.0" (the current version has been in the store since before iOS 10 existed), it does crash citing a missing NSCameraUsageDescription when it attempts to access the camera.)
Furthermore, my reading of the documentation above suggests that I should be including an entry for NSBluetoothPeripheralUsageDescription.
Is there any other documentation that I've missed that lists which actual API calls are covered by which privacy purpose strings?
Do I need to add an entry for NSBluetoothPeripheralUsageDescription to my Info.plist?
Is there any harm in adding such an entry if it turns out not to be required?
Yes you're definitely need it, it was optional in pre-ios10 but now you have to explicit add the comment into the info.plist
IF you're build with iOS10. It will crash the app but If you build with pre-ios 10 it's fine. It's based on Xcode build not based on Device version
So basically, next time you update the app you need to add it.
and By the way, I couldn't find document for it, this is my own experience that we have when shifting from iOS9 to iOS10