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


当前回答

如果我想将.plist转换为Swift字典,这是我所做的:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist") {
  if let dict = NSDictionary(contentsOfFile: path) as? Dictionary<String, AnyObject> {
    // use swift dictionary as normal
  }
}

为Swift 2.0编辑:

if let path = NSBundle.mainBundle().pathForResource("Config", ofType: "plist"), dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject] {
    // use swift dictionary as normal
}

为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
}

其他回答

你可以使用它,我在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?

步骤1:简单和最快的方法来解析plist在swift 3+

extension Bundle {

    func parsePlist(ofName name: String) -> [String: AnyObject]? {

        // check if plist data available
        guard let plistURL = Bundle.main.url(forResource: name, withExtension: "plist"),
            let data = try? Data(contentsOf: plistURL)
            else {
                return nil
        }

        // parse plist into [String: Anyobject]
        guard let plistDictionary = try? PropertyListSerialization.propertyList(from: data, options: [], format: nil) as? [String: AnyObject] else {
            return nil
        }

        return plistDictionary
    }
}

第二步:使用方法:

Bundle().parsePlist(ofName: "Your-Plist-Name")

Swift -读写plist和文本文件....

override func viewDidLoad() {
    super.viewDidLoad()

    let fileManager = (NSFileManager .defaultManager())
    let directorys : [String]? = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.AllDomainsMask, true) as? [String]

    if (directorys != nil){
        let directories:[String] = directorys!;
        let dictionary = directories[0]; //documents directory


        //  Create and insert the data into the Plist file  ....
        let plistfile = "myPlist.plist"
        var myDictionary: NSMutableDictionary = ["Content": "This is a sample Plist file ........."]
        let plistpath = dictionary.stringByAppendingPathComponent(plistfile);

        if !fileManager .fileExistsAtPath(plistpath){//writing Plist file
            myDictionary.writeToFile(plistpath, atomically: false)
        }
        else{            //Reading Plist file
            println("Plist file found")

            let resultDictionary = NSMutableDictionary(contentsOfFile: plistpath)
            println(resultDictionary?.description)
        }


        //  Create and insert the data into the Text file  ....
        let textfile = "myText.txt"
        let sampleText = "This is a sample text file ......... "

        let textpath = dictionary.stringByAppendingPathComponent(textfile);
        if !fileManager .fileExistsAtPath(textpath){//writing text file
            sampleText.writeToFile(textpath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
        } else{
            //Reading text file
            let reulttext  = String(contentsOfFile: textpath, encoding: NSUTF8StringEncoding, error: nil)
            println(reulttext)
        }
    }
    else {
        println("directory is empty")
    }
}

通过尼克的回答转换成一个方便的扩展:

extension Dictionary {
    static func contentsOf(path: URL) -> Dictionary<String, AnyObject> {
        let data = try! Data(contentsOf: path)
        let plist = try! PropertyListSerialization.propertyList(from: data, options: .mutableContainers, format: nil)

        return plist as! [String: AnyObject]
    }
}

用法:

let path = Bundle.main.path(forResource: "plistName", ofType: "plist")!
let url = URL(fileURLWithPath: path)
let dict = Dictionary<String, AnyObject>.contentsOf(path: url)

我敢打赌,它也可以为数组创建类似的扩展