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
语法似乎已更改,而我能找到的其他问题是由错误的密钥类型引起的,考虑到我在写出之前没有进行修改,这很奇怪.这是重现该错误的完整代码:
I'd like to read it in from my MainBundle
, modify it, and write it out to my .Documents
. However, even if I leave it unmodified, the write fails. The Swift
syntax seems to have changed since this question, and the other questions I could find were caused by incorrect key types, which would be odd given that I'm not modifying before writing out. Here is the complete code to reproduce the error:
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
方法失败?
I made a silly logic error in the original example (missing !
in the last line) which was causing it look like it was failing when it wasn't. However, the example now fails with the URL
method but works with either the path
or String
interpolation methods. Why is the URL
method failing?
推荐答案
这是错误的:
guard let docsURL = NSURL(string: docsString) else { ... }
要从文件路径创建NSURL
,请使用
To create an NSURL
from a file path, use
let docsURL = NSURL(fileURLWithPath: docsString)
相反,您不能使用字符串插值来创建文件路径
从NSURL
:
Conversely, you cannot use string interpolation to create a file path
from an NSURL
:
let plistString = "\(plistURL)"
改为使用.path
方法:
let plistPath = plistURL.path!
或者更好的方法是,使用writeToURL()
方法编写字典,
那么您不必将URL转换为路径.
Or better, use the writeToURL()
method to write your dictionary,
then you don't have to convert the URL to a path.
这篇关于Swift:从MainBundle读取plist并直接写入Documents失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!