Swift:从 MainBundle 读取 plist 并直接写入 Documents 失败
Swift: Reading a plist from MainBundle and writing directly to Documents fails
获取以下文件,命名为 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
中。但是,即使我保留它 未修改 ,写入也会失败。 Swift
语法似乎自 this question, and the other questions I could find were caused by 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
方法失败,但可以使用 path
或 String
插值方法。为什么 URL
方法失败?
这是错误的:
guard let docsURL = NSURL(string: docsString) else { ... }
要从文件路径创建 NSURL
,请使用
let docsURL = NSURL(fileURLWithPath: docsString)
反之,不能使用字符串插值来创建文件路径
来自 NSURL
:
let plistString = "\(plistURL)"
改用.path
方法:
let plistPath = plistURL.path!
或者更好的是,使用 writeToURL()
方法编写字典,
那么您不必将 URL 转换为路径。
获取以下文件,命名为 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
中。但是,即使我保留它 未修改 ,写入也会失败。 Swift
语法似乎自 this question, and the other questions I could find were caused by 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
方法失败,但可以使用 path
或 String
插值方法。为什么 URL
方法失败?
这是错误的:
guard let docsURL = NSURL(string: docsString) else { ... }
要从文件路径创建 NSURL
,请使用
let docsURL = NSURL(fileURLWithPath: docsString)
反之,不能使用字符串插值来创建文件路径
来自 NSURL
:
let plistString = "\(plistURL)"
改用.path
方法:
let plistPath = plistURL.path!
或者更好的是,使用 writeToURL()
方法编写字典,
那么您不必将 URL 转换为路径。