How to read a Property List (plist) into the code

Swift Workflow

When I want to keep some information or configuration out of a code base and don't want something fancy, I usually save it as Property List file (.plist).

Create a plist file #

To create a plist file, it just as simple as creating a new class.

  1. Click menu File > New > File... (⌘ - CMD + N).)
  2. Under Resource section, select Property List
  3. That's it
Create a Property List
Create a Property List

Read a plist file #

There are two ways that I usually use to read it back (There is only one now since another one is deprecated, but I will leave it here for completeness).

NSDictionary and NSArray Deprecated #

Dictionary #

I use this since the Objective-C time. You can read it directly to NSDictionary.

var config: [String: Any]?
if let infoPlistPath = Bundle.main.path(forResource: "Config", ofType: "plist"),
let dict = NSDictionary(contentsOfFile: infoPlistPath) as? [String: Any] {
config = dict
}

Array #

The root level of Property List can be either Array or Dictionary, so you can also read it to NSArray if your plist is an array.

var config: [Any]?
if let infoPlistPath = Bundle.main.path(forResource: "Config", ofType: "plist"),
let arr = NSArray(contentsOfFile: infoPlistPath) as? [Any]
{
config = arr
}

Too bad, the above solutions are deprecated. Both NSArray and NSDictionary initializer are deprecated in iOS 11.

PropertyListSerialization #

Since iOS 4, with a help of .propertyList(from:options:format:) in PropertyListSerialization, we can deserialize plist into Dictionary and Array. It might a bit verbose, but it get the job done.

Dictionary #

var config: [String: Any]?
if let infoPlistPath = Bundle.main.url(forResource: "Config", withExtension: "plist") {
do {
let infoPlistData = try Data(contentsOf: infoPlistPath)

if let dict = try PropertyListSerialization.propertyList(from: infoPlistData, options: [], format: nil) as? [String: Any] {
config = dict
}
} catch {
print(error)
}
}

Array #

The only difference between getting array and dictionary here is just a matter of casting.

var config: [Any]?
if let infoPlistPath = Bundle.main.url(forResource: "Config", withExtension: "plist") {
do {
let infoPlistData = try Data(contentsOf: infoPlistPath)

if let arr = try PropertyListSerialization.propertyList(from: infoPlistData, options: [], format: nil) as? [Any] {
config = arr
}
} catch {
print(error)
}
}

These are a quick way of saving and reading data from a file.


Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Tweet Share

If you enjoy this article, you can subscribe to the weekly newsletter.

Every Friday, you’ll get a quick recap of all articles and tips posted on this site — entirely for free.

← Home