I was finalizing an update to our Relocation America International app this week. Everything was going swimmingly. I built the app using the PhoneGap Build process, retrieved the binary, and uploaded it to the App Store. That’s when I received this:

Dear developer,

We have discovered one or more issues with your recent delivery for “RAInternational Connect”. To process your delivery, the following issues must be corrected:

Missing Info.plist key – This app attempts to access privacy-sensitive data without a usage description. The app’s Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data.

Once these issues have been corrected, you can then redeliver the corrected binary.

Regards,

The App Store team

The dreaded app rejection message. Ugh!

I did what most good developers would do and turned to Google to help me out of my quandary. Unfortunately, the most highly rated results were all over the map. Here were a few of the recommended solutions:

  • Use Cordova to remove the camera plugin and reinstall it using the options that add the privacy settings. Unfortunately, since we’re using PhoneGap Build, this wasn’t an option.
  • Take the *.ipa file to a Mac, open it in Xcode, find the info.plist file, and manually edit it. Since I had never used Xcode before, I wasn’t exactly chomping at the bit to go this route. Plus, the result wouldn’t be repeatable. I didn’t want to add another step to our build process for the app.
  • Install a plug-in that let me stuff the fields into the info.plist. This was certainly an option, but I was hesitant to create yet another plug-in dependency this close to release. Due to past experiences with plug-ins late in the game, I was having a hot stove moment and didn’t want to get burned again.

Fortunately, the PhoneGap Build documentation, which is usually less than helpful (sorry Adobe, just telling it like it is), came through. Their article on modifying manifests saved my bacon (click here for link).

It turns out, all I needed to add was a new config.xml file entry that targeted NSPhotoLibraryUsageDescription. Here is what I added, no plug-in required:

<gap:config-file platform="ios" parent="NSPhotoLibraryUsageDescription">
    <string>For uploading receipt images</string>
</gap:config-file>

Since I was using the camera plugin, I also added another entry for NSCameraUsageDescription.

Then it was rinse & repeat, meaning rebuild, grab the binary, and upload to Apple. This time, success! I got the message we all love:

You can now use this build for TestFlight testing or submit it to the App Store.

If you have any questions regarding your app, click Contact Us in iTunes Connect.

Regards,

The App Store team

While this seems like quite the hassle, I’m actually happy that Apple is concerned about user privacy. It helps users to understand exactly why apps need permission for specific features. Therefore, be certain that you put a little thought into the message that goes into the string field. The user of your app will see this message when they access the feature. In fact, I wouldn’t mind seeing Android following suit in the near future.