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?
CodePudding user response:
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.