Swift:从MainBundle读取一个plist并直接写入Documents

时间:2016-01-18 08:52:57

标签: swift plist

获取名为Permissions.plist的以下文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
    <key>SomeKey</key>
    <false/>
    </dict>
</plist>

我想从我的MainBundle中读取它,修改它,并将其写入我的.Documents。但是,即使我将其保留为未修改,写入也会失败。自this question以来,Swift语法似乎发生了变化,我可以找到的其他问题是由incorrect key types引起的,考虑到我在写出之前没有修改,这将是奇怪的。以下是重现错误的完整代码:

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Read in the plist from the main bundle.
        guard let path = NSBundle.mainBundle().pathForResource("Permissions", ofType: "plist") else {
            NSLog("Path could not be created.")
            return
        }

        guard NSFileManager.defaultManager().fileExistsAtPath(path) else {
            NSLog("File does not exist.")
            return
        }

        guard let resultDictionary = NSMutableDictionary(contentsOfFile: path) else {
            NSLog("Contents could not be read.")
            return
        }

        print(resultDictionary) // { Facebook = 0; }

        // Write it to the documents directory
        let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true) as NSArray

        guard let docsString = paths[0] as? String else {
            NSLog("Couldn't find documents directory; permissions could not be updated.")
            return
        }

        guard let docsURL = NSURL(string: docsString) else {
            NSLog("Couldn't convert the path to a URL; permissions could not be updated.")
            return
        }

        let plistURL = docsURL.URLByAppendingPathComponent("Permissions.plist")
        let plistPath = plistURL.path!
        let plistString = "\(plistURL)"

        if !resultDictionary.writeToURL(plistURL, atomically: false) {
            NSLog("Writing file to disk via url was unsucessful.") // Failure
        }

        if !resultDictionary.writeToFile(plistPath, atomically: false) {
            NSLog("Writing file to disk via path was unsucessful.")
        }

        if !resultDictionary.writeToFile(plistString, atomically: false) {
            NSLog("Writing file to disk via path was unsucessful.")
        }

        print("URL: ",NSMutableDictionary(contentsOfURL: plistURL)) // nil
        print("Path: ",NSMutableDictionary(contentsOfFile: plistPath)) // Prints
        print("String: ",NSMutableDictionary(contentsOfFile: plistString)) // Prints

    }

}

修改

我在原始示例中犯了一个愚蠢的逻辑错误(在最后一行中丢失了!),这导致它看起来像是在它没有时失败。但是,该示例现在无法使用URL方法,但可以使用pathString插值方法。为什么URL方法失败了?

1 个答案:

答案 0 :(得分:2)

这是错误的:

guard let docsURL = NSURL(string: docsString) else { ... }

要从文件路径创建NSURL,请使用

let docsURL = NSURL(fileURLWithPath: docsString)

相反,您不能使用字符串插值来创建文件路径 来自NSURL

let plistString = "\(plistURL)"

请改用.path方法:

let plistPath = plistURL.path!

或者更好,使用writeToURL()方法编写字典, 那么你就不必将URL转换为路径。