What is Info.plist for, and which keys matter most?

6.7.1 · L2 · Interview

Predict first

What does this print?

import Foundation

let xml = #"<?xml version="1.0" encoding="UTF-8"?><plist version="1.0"><dict><key>UIBackgroundModes</key><array><string>audio</string><string>fetch</string></array><key>CFBundleShortVersionString</key><string>1.2</string></dict></plist>"#
let info = try PropertyListSerialization.propertyList(from: Data(xml.utf8), format: nil) as! [String: Any]
print(info["UIBackgroundModes"] as! [String], info["CFBundleShortVersionString"] as! String)
  • ["audio", "fetch"] 1.2
  • [] 1.2
  • Crash

Mental model. It is the passport your app presents at the border: name, version, and a list of what it intends to do there.

Info.plist is the app’s declaration to the system, read before your code runs. It identifies the app (CFBundleIdentifier, CFBundleShortVersionString, CFBundleVersion), describes the scene configuration (UIApplicationSceneManifest) and launch screen, and lists the capabilities the app will use: UIBackgroundModes, BGTaskSchedulerPermittedIdentifiers, and the usage descriptions for protected resources (a missing one crashes on first use). It also configures the URL schemes the app handles (CFBundleURLTypes), LSApplicationQueriesSchemes for the schemes it may query with canOpenURL, App Transport Security exceptions, and export-compliance flags.

Modern Xcode projects can generate much of it from build settings (GENERATE_INFOPLIST_FILE), with a small file for the rest. Read values at runtime with Bundle.main.object(forInfoDictionaryKey:); the file is plain property-list data, so the same parsing rules apply as for any plist, and it is part of the signed bundle, so it cannot change after build. Review it in code review as you would code: a stray background mode or an ATS exception is a policy and security decision.

A plist is just structured data: the array of background modes and the version string come back as ordinary Swift values.

Common traps

  • Leaving out a usage description. The first access to that resource crashes with a message naming the key.
  • Disabling App Transport Security globally to “fix” one server. Add a narrow exception for that domain, or fix the server.

They might follow up with

  • Why does canOpenURL return false for an installed app? Its scheme is not listed in LSApplicationQueriesSchemes.
  • Where do the version numbers show up? In the App Store, Settings and your own about screen via Bundle.main.

Related questions

  • 6.1.4 How do privacy permissions work, and what do you do after the user says no?
  • 6.5.2 What do the audio, location, VoIP and remote-notification background modes allow, and what is the catch?
  • 2.5.6 What is a property list, and where do you meet one?
  • 2.6.1 What is a Bundle, and how do you load a resource from it?

What is the difference between a custom URL scheme and a universal… →