MacOS,Swift 4。
我想将数据存储在plist中。我可以加载这些值,但是在将它们写出时,它们的格式不正确。
这样,我正在加载plist(以表格视图显示它),效果很好:
func loadBooks() {
let path = dataFilePath() // /com.name.books/Data/Documents/
do {
let data = try Data(contentsOf: path)
let decoder = PropertyListDecoder()
let plist = try decoder.decode([String: [Book]].self, from: data)
books = plist["BooksData"]!
} catch {
print("Error occurred: \(error.localizedDescription)")
}
}
这是我正在加载的plist:
<plist version="1.0">
<dict>
<key>BooksData</key>
<array>
<dict>
<key>author</key>
<string>First Author</string>
<key>title</key>
<string>First Title</string>
<key>lentBy</key>
<string>Person</string>
</dict>
<dict>
<key>author</key>
<string>Second Author</string>
<key>title</key>
<string>Book Title2</string>
<key>lentBy</key>
<string>Another Person</string>
</dict>
</array>
</dict>
</plist>
我试图像这样将数组写回到plist:
func saveBooks() {
let data = books
do {
let encoder = PropertyListEncoder()
var plist = try encoder.encode(data)
try plist.write(to: dataFilePath())
} catch {
print("Error occured: \(error.localizedDescription)")
}
}
plist的内容失去了其“包装”和键(“ BooksData”),因此无法再通过loadBooks()函数读取。
这是输出:
<plist version="1.0">
<array>
<dict>
<key>author</key>
<string>First Author</string>
<key>title</key>
<string>First Title</string>
<key>lentBy</key>
<string>Person</string>
</dict>
<dict>
<key>author</key>
<string>Second Author</string>
<key>title</key>
<string>Book Title2</string>
<key>lentBy</key>
<string>Another Person</string>
</dict>
</array>
</plist>
我玩过NSMutableDictionary()
,试图用dict.setObject(plist, forKey: "BooksData")
重新包装并用dict.write(toFile: dataFilePath().absoluteString, atomically: true)
编写。
let encoder = PropertyListEncoder()
var plist = try encoder.encode(data)
dict.setObject(plist, forKey: "BooksData" as NSCopying)
dict.write(toFile: dataFilePath().absoluteString, atomically: true)
print(dict)
打印字典返回
{
BooksData = <62706c69 73743030 a401080c 10d30203 04050607 55746974 6c655661 7574686f 72566c65 6e744279 59427563 68746974 656c5b46 696e6b2c 20457567 656e546e 6f6e65d3 02030409 0a0b5f10 14457266 61687275 6e672075 6e642055 72746569 6c5f100f 48757373 65726c2c 2045646d 756e645a 50617472 69636b20 5379d302 03040d0e 0f5f101a 4b726974 696b2064 65722072 65696e65 6e205665 726e756e 66745e4b 616e742c 20496d6d 616e7565 6c50d302 03041112 0f5b4369 74612041 63746976 615e4172 656e6474 2c204861 6e6e6168 080d141a 2128323e 434a6173 7e85a2b1 b2b9c500 00000000 00010100 00000000 00001300 00000000 00000000 00000000 0000d4>;
}
文件甚至没有被写出,即dataFilePath()上的旧文件保持不变。
答案可以在PropertyListSerialization.propertyList(from:options:format:)
中吗?还是CodingKeys
?还是encode(title, forKey:"BooksData")
(?)等? NSMutableArray
? KeyedDecodingContainer
,unkeyedContainer
等? NSKeyedArchiver
?
这似乎是一个简单的任务,但我只是做对了。似乎有一些与此相关的主题,但是并没有真正应用或提供了解决此问题的关键信息。该文档也没有为我阐明任何内容,我需要一些具体的提示。
请帮助。
答案 0 :(得分:0)
由于期望的类型为adc
,因此您必须手动
[String: [Book]]
但是,如果plist仅包含func saveBooks() {
do {
let encoder = PropertyListEncoder()
let plistData = try encoder.encode(["BooksData":books])
try plistData.write(to: dataFilePath())
} catch {
print("Error occured:", error) // never ever print `localizedDescription`
}
}
数组,则仅保存该数组。此外,我建议将可能的错误移交给呼叫者
books
然后save方法匹配类型
var books = [Book]()
func loadBooks() throws {
let path = dataFilePath() // /com.name.books/Data/Documents/
let data = try Data(contentsOf: path)
let decoder = PropertyListDecoder()
books = try decoder.decode([Book].self, from: data)
}