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


当前回答

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

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

到目前为止(在我看来),这是访问plist最简单和最有效的方法,但在未来,我希望苹果将添加更多的功能(比如使用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的所有功能。

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")
    }
}

最好使用本机字典和数组,因为它们已经针对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
        }
    }
}

Swift 4.0 iOS 11.2.6列表解析和代码解析它,基于https://stackoverflow.com/users/3647770/ashok-r上面的答案。

<?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">
<array>
  <dict>
    <key>identity</key>
    <string>blah-1</string>
    <key>major</key>
    <string>1</string>
    <key>minor</key>
    <string>1</string>
    <key>uuid</key>
    <string>f45321</string>
    <key>web</key>
    <string>http://web</string>
</dict>
<dict>
    <key>identity</key>
    <string></string>
    <key>major</key>
    <string></string>
    <key>minor</key>
    <string></string>
    <key>uuid</key>
    <string></string>
    <key>web</key>
    <string></string>
  </dict>
</array>
</plist>

do {
   let plistXML = try Data(contentsOf: url)
    var plistData: [[String: AnyObject]] = [[:]]
    var propertyListFormat =  PropertyListSerialization.PropertyListFormat.xml
        do {
            plistData = try PropertyListSerialization.propertyList(from: plistXML, options: .mutableContainersAndLeaves, format: &propertyListFormat) as! [[String:AnyObject]]

        } catch {
            print("Error reading plist: \(error), format: \(propertyListFormat)")
        }
    } catch {
        print("error no upload")
    }