我在玩苹果的新Swift编程语言,遇到了一些问题…
目前我试图读取一个plist文件,在Objective-C中,我会做以下工作来获取内容作为NSDictionary:
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Config" ofType:@"plist"];
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:filePath];
我如何得到一个plist作为一个字典在Swift?
我假设我可以得到路径到plist:
let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")
当这工作(如果它是正确的?):我如何获得内容作为一个字典?
还有一个更普遍的问题:
是否可以使用默认的NS*类?我想是的……还是我遗漏了什么?据我所知,默认框架NS*类仍然有效,可以使用吗?
斯威夫特4.0
现在可以使用decodedable协议将.plist解码为自定义结构。我将介绍一个基本的例子,对于更复杂的。plist结构,我建议阅读Decodable/Encodable(一个很好的资源是:https://benscheirman.com/2017/06/swift-json/)。
首先将结构设置为.plist文件的格式。对于这个例子,我将考虑一个根级字典和3个条目:1个字符串键“name”,1个Int键“age”,1个布尔键“single”。下面是结构体:
struct Config: Decodable {
private enum CodingKeys: String, CodingKey {
case name, age, single
}
let name: String
let age: Int
let single: Bool
}
很简单。现在是最酷的部分。使用PropertyListDecoder类,我们可以很容易地将.plist文件解析为这个结构体的实例化:
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)
}
不用担心太多代码,而且都在Swift中。更好的是,我们现在有一个Config结构的实例化,我们可以很容易地使用:
let config = parseConfig()
print(config.name)
print(config.age)
print(config.single)
打印。plist中“name”、“age”和“single”键的值。
在SWIFT语言中,你可以这样读plist:
let path = NSBundle.mainBundle().pathForResource("PriceList", ofType: "plist")
let dict = NSDictionary(contentsOfFile: path)
读单个字典值:
let test: AnyObject = dict.objectForKey("index1")
如果你想在plist中获得完整的多维字典:
let value: AnyObject = dict.objectForKey("index2").objectForKey("date")
下面是plist:
<plist version="1.0">
<dict>
<key>index2</key>
<dict>
<key>date</key>
<string>20140610</string>
<key>amount</key>
<string>110</string>
</dict>
<key>index1</key>
<dict>
<key>amount</key>
<string>125</string>
<key>date</key>
<string>20140212</string>
</dict>
</dict>
</plist>
你仍然可以在Swift中使用nsdictionary:
Swift 4
var nsDictionary: NSDictionary?
if let path = Bundle.main.path(forResource: "Config", ofType: "plist") {
nsDictionary = NSDictionary(contentsOfFile: path)
}
Swift 3+
if let path = Bundle.main.path(forResource: "Config", ofType: "plist"),
let myDict = NSDictionary(contentsOfFile: path){
// Use your myDict here
}
以及旧版本的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
}
NSClasses仍然可用,完全可以在Swift中使用。我想他们可能很快就会把重点转移到swift上,但是目前swift api并没有核心NSClasses的所有功能。