我在玩苹果的新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*类仍然有效,可以使用吗?


当前回答

你可以使用它,我在github https://github.com/DaRkD0G/LoadExtension中创建了一个简单的字典扩展

extension Dictionary {
    /**
        Load a Plist file from the app bundle into a new dictionary

        :param: File name
        :return: Dictionary<String, AnyObject>?
    */
    static func loadPlistFromProject(filename: String) -> Dictionary<String, AnyObject>? {

        if let path = NSBundle.mainBundle().pathForResource("GameParam", ofType: "plist") {
            return NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject>
        }
        println("Could not find file: \(filename)")
        return nil
    }
}

你可以用它来计算负载

/**
  Example function for load Files Plist

  :param: Name File Plist
*/
func loadPlist(filename: String) -> ExampleClass? {
    if let dictionary = Dictionary<String, AnyObject>.loadPlistFromProject(filename) {
        let stringValue = (dictionary["name"] as NSString)
        let intergerValue = (dictionary["score"] as NSString).integerValue
        let doubleValue = (dictionary["transition"] as NSString).doubleValue

        return ExampleClass(stringValue: stringValue, intergerValue: intergerValue, doubleValue: doubleValue)
    }
    return nil
}

其他回答

下面是一个基于@connor的回答的简短版本

guard let path = Bundle.main.path(forResource: "GoogleService-Info", ofType: "plist"),
    let myDict = NSDictionary(contentsOfFile: path) else {
    return nil
}

let value = dict.value(forKey: "CLIENT_ID") as! String?

在我的情况下,我创建了一个NSDictionary称为appSettings并添加所有需要的键。对于这种情况,解决方案是:

if let dict = NSBundle.mainBundle().objectForInfoDictionaryKey("appSettings") {
  if let configAppToken = dict["myKeyInsideAppSettings"] as? String {

  }
}

最好使用本机字典和数组,因为它们已经针对swift进行了优化。也就是说你可以使用NS。我认为这种情况证明了这一点。下面是你如何实现它:

var path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist")
var dict = NSDictionary(contentsOfFile: path)

到目前为止(在我看来),这是访问plist最简单和最有效的方法,但在未来,我希望苹果将添加更多的功能(比如使用plist)到本地字典中。

斯威夫特3.0

如果你想从.plist读取一个“二维数组”,你可以这样尝试:

if let path = Bundle.main.path(forResource: "Info", ofType: "plist") {
    if let dimension1 = NSDictionary(contentsOfFile: path) {
        if let dimension2 = dimension1["key"] as? [String] {
            destination_array = dimension2
        }
    }
}

我已经创建了一个简单的字典初始化器替换NSDictionary(contentsOfFile: path)。只要去掉NS。

extension Dictionary where Key == String, Value == Any {

    public init?(contentsOfFile path: String) {
        let url = URL(fileURLWithPath: path)

        self.init(contentsOfURL: url)
    }

    public init?(contentsOfURL url: URL) {
        guard let data = try? Data(contentsOf: url),
            let dictionary = (try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: Any]) ?? nil
            else { return nil }

        self = dictionary
    }

}

你可以这样使用它:

let filePath = Bundle.main.path(forResource: "Preferences", ofType: "plist")!
let preferences = Dictionary(contentsOfFile: filePath)!
UserDefaults.standard.register(defaults: preferences)