Search code examples
swiftplistcodableproperty-list

How to read in com.apple.symbolichotkeys.plist with Swift on macOS?


I am trying to read a value from this property list file:

~/Library/Preferences/com.apple.symbolichotkeys.plist

to see if some Hotkey is enabled. I tried to read the plist file with Codable:

import Foundation

let xml = """
    <?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">
    <dict>
    <key>AppleSymbolicHotKeys</key>
    <dict>
    <key>10</key>
    <dict>
        <key>enabled</key>
        <true/>
        <key>value</key>
        <dict>
            <key>parameters</key>
            <array>
                <integer>65535</integer>
                <integer>96</integer>
                <integer>8650752</integer>
            </array>
            <key>type</key>
            <string>standard</string>
        </dict>
    </dict>
    <key>11</key>
    <dict>
        <key>enabled</key>
        <true/>
        <key>value</key>
        <dict>
            <key>parameters</key>
            <array>
                <integer>65535</integer>
                <integer>97</integer>
                <integer>8650752</integer>
            </array>
            <key>type</key>
            <string>standard</string>
        </dict>
    </dict>
    </dict>
    </dict>
    </plist>
    """

struct Root: Codable {
    var AppleSymbolicHotKeys: Hotkey

    struct Hotkey: Codable {
        var someKey: Property // << key is an integer, not a static key!
    
        struct Property: Codable {
            var enabled: Bool
            var value: Value
        
            struct Value: Codable {
                var parameter: [Int]
                var type: String
            }
        }
    }
}
  
if let data = xml.data(using: .utf8) {
    let decoder = PropertyListDecoder()
    let hotkeys = try? decoder.decode(Root.self, from: data)
    print("Decoded:", hotkeys)
}

In my Playground, it returns:

Decoded: nil

In the above code, I copied a part of the xml contents for reference. I tried with reading the real file too, it returns data but is not decoding.

I understand that someKey in my model can not work, since each "key" has a new numeric value, but how can I make it work?


Solution

  • This is how the model struct looks following the advice of @vadian, and it works:

    struct Root: Codable {
        var AppleSymbolicHotKeys: [String: Property]
        
        struct Property: Codable {
            var enabled: Bool
            var value: Value
            
            struct Value: Codable {
                var parameters: [Int]
                var type: String
            }
        }
    }