I'm writing a Mac command line tool in Swift 5 and I'm trying to parse a Plist which contains a nested dictionary of values named "TestValues". I want to add each key pair from this dictionary to an array but I'm just hitting a brick wall.
The Plist looks like this:
<?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>TestValues</key>
<dict>
<key>TestString</key>
<string>This is my test string value</string>
<key>TestInt</key>
<integer>4</integer>
<key>AnotherTestString</key>
<string>This is my other test string value</string>
<key>TestBool</key>
<true/>
</dict>
</dict>
</plist>
And my code:
struct CustomPrefs: Codable {
var TestValues: [TestValuePrefs]
}
struct TestValuePrefs: Codable {
var TestString: String
var TestInt: Int
var AnotherTestString: String
var TestBool: Bool
}
func getCustomPrefs() -> CustomPrefs? {
let decoder = PropertyListDecoder()
let url = URL(fileURLWithPath: "/Library/Preferences/com.test.preferences.plist")
if let data = try? Data(contentsOf: url) {
if let customPreferences = try? decoder.decode(CustomPrefs.self, from: data) {
print("Returning custom prefs")
return customPreferences
}
}
print("Returning nil")
return nil
}
let preferenceArray = (getCustomPrefs()?.TestValues)
print(preferenceArray ?? "")
But I just keep getting nil from the "getCustomPrefs" function. Can anyone see where I'm going wrong?
The TestValues
var in CustomPrefs
isn't an array or dictionary but rather the TestValuePrefs
object.
The following should do the trick:
struct CustomPrefs: Decodable {
let TestValues: TestValuePrefs
struct TestValuePrefs: Decodable {
let TestString: String
let TestInt: Int
let AnotherTestString: String
let TestBool: Bool
}
}
func getCustomPrefs() -> CustomPrefs? {
let decoder = PropertyListDecoder()
let url = URL(fileURLWithPath: "/Library/Preferences/com.test.preferences.plist")
do {
let data = try Data(contentsOf: url)
let customPreferences = try decoder.decode(CustomPrefs.self, from: data)
return customPreferences
}
catch {
print("Error: \(error)")
}
return nil
}
I'd also recommend using CodingKeys
to avoid using capitalized variables.