Read from plist file in iOS / Swift

By | January 29, 2025

What is Plist file?
Property List (Plist) file is a specialized file format used to store structured data. Plist files can contain various data types, including dictionaries, arrays, strings, numbers, dates, and binary data. They are widely used in Apple development for various purposes, such as app configurationuser preferences, and data serialization.

Plist files have a .plist file extension and are often human-readable in XML format, but they can also be in binary format for efficiency. Here’s a simple example of a Plist file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>name</key>
        <string>Item 1</string>
        <key>value</key>
        <integer>1</integer>
    </dict>
    <dict>
        <key>name</key>
        <string>Item 2</string>
        <key>value</key>
        <integer>2</integer>
    </dict>
</array>
</plist>

Reading data from a plist:

I’ve provided two methods to read from a plist file:

  1. Using PropertyListDecoder (Method 1):
    • This is the modern Swift way
    • Works with Codable types
    • Type-safe and preferred when working with structured data
// Method 1: Reading from main bundle
func readPlistFromBundle<T>(fileName: String) -> [T]? {
    // Get path to the plist file in main bundle
    if let path = Bundle.main.path(forResource: fileName, ofType: "plist") {
        // Create URL from the path
        let url = URL(fileURLWithPath: path)
        
        do {
            // Read data from plist file
            let data = try Data(contentsOf: url)
            
            // Create property list decoder
            let decoder = PropertyListDecoder()
            
            // Decode the plist data into array
            let array = try decoder.decode([T].self, from: data)
            return array
        } catch {
            print("Error reading plist: \(error)")
            return nil
        }
    }
    return nil
}

2. Using PropertyListSerialization (Method 2):

  • More flexible for reading arbitrary plist structures
  • Returns dictionary format
  • Useful when dealing with legacy plists or dynamic data
// Method 2: Reading directly using PropertyList serialization
func readPlistUsingPropertyList(fileName: String) -> [[String: Any]]? {
    if let path = Bundle.main.path(forResource: fileName, ofType: "plist"),
       let xml = FileManager.default.contents(atPath: path) {
        do {
            // Parse plist data
            let plistData = try PropertyListSerialization.propertyList(from: xml,
                                                                      options: .mutableContainersAndLeaves,
                                                                      format: nil)
            return plistData as? [[String: Any]]
        } catch {
            print("Error reading plist: \(error)")
            return nil
        }
    }
    return nil
}

To use this code:

  1. First, make sure your plist file is added to your Xcode project and included in your target
  2. Create your plist file with the correct structure
  3. If using Method 1, create a matching Swift type that conforms to Codable as shown below.
// Example usage with a custom type
struct Item: Codable {
    let name: String
    let value: Int
}

4. Call the appropriate function with your plist filename (without the .plist extension)

// Example of how to use these functions
func example() {
    // Using Method 1 with custom type
    if let items: [Item] = readPlistFromBundle(fileName: "Items") {
        print("Items from plist: \(items)")
    }
    
    // Using Method 2 for dictionary array
    if let dictArray = readPlistUsingPropertyList(fileName: "Items") {
        print("Dictionary array from plist: \(dictArray)")
    }
}

Thank you for reading!

Leave a Reply

Your email address will not be published. Required fields are marked *