How do I get a plist as a Dictionary in Swift?
You can still use NSDictionaries in Swift:
For Swift 4
var nsDictionary: NSDictionary?
if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
nsDictionary = NSDictionary(contentsOfFile: path)
}
For Swift 3+
if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
let myDict = NSDictionary(contentsOfFile: path){
// Use your myDict here
}
And older versions of Swift
var myDict: NSDictionary?
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
myDict = NSDictionary(contentsOfFile: path)
}
if let dict = myDict {
// Use your dict here
}
The NSClasses are still available and perfectly fine to use in Swift. I think they'll probably want to shift focus to swift soon, but currently the swift APIs don't have all the functionality of the core NSClasses.
This is what I do if I want to convert a .plist to a Swift dictionary:
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
// use swift dictionary as normal
}
}
Edited for Swift 2.0:
if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
// use swift dictionary as normal
}
Edited for Swift 3.0:
if let path = Bundle.main.path(forResource: "Config", ofType: "plist"), let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
// use swift dictionary as normal
}
Swift 4.0
You can now use the Decodable protocol to Decode a .plist into a custom struct. I will go over a basic example, for more complicated .plist structures I recommend reading up on Decodable/Encodable (a good resource is here: https://benscheirman.com/2017/06/swift-json/).
First setup your struct into the format of your .plist file. For this example I will consider a .plist with a root level Dictionary and 3 entries: 1 String with key "name", 1 Int with key "age", and 1 Boolean with key "single". Here is the struct:
struct Config: Decodable {
private enum CodingKeys: String, CodingKey {
case name, age, single
}
let name: String
let age: Int
let single: Bool
}
Simple enough. Now the cool part. Using the PropertyListDecoder class we can easily parse the .plist file into an instantiation of this struct:
func parseConfig() -> Config {
let url = Bundle.main.url(forResource: "Config", withExtension: "plist")!
let data = try! Data(contentsOf: url)
let decoder = PropertyListDecoder()
return try! decoder.decode(Config.self, from: data)
}
Not much more code to worry about, and its all in Swift. Better yet we now have an instantiation of the Config struct that we can easily use:
let config = parseConfig()
print(config.name)
print(config.age)
print(config.single)
This Prints the value for the "name", "age", and "single" keys in the .plist.