为啥这个 plist 读/写失败?
Posted
技术标签:
【中文标题】为啥这个 plist 读/写失败?【英文标题】:Why is this plist read/write failing?为什么这个 plist 读/写失败? 【发布时间】:2018-02-21 15:49:08 【问题描述】:我正在学习 ios 教程,但遇到了 plist 问题。我有这个反射代码,我的应用程序中的模型对象:
struct Reflection
let title: String
let body: String
let author: String
let favorite: Bool
let creationDate: Date
let id: UUID
extension Reflection
var plistRepresentation: [String: AnyObject]
return [
"title": title as AnyObject,
"body": body as AnyObject,
"author": author as AnyObject,
"favorite": favorite as AnyObject,
"creationDate": creationDate as AnyObject,
"id": id as AnyObject
]
init(plist: [String: AnyObject])
title = plist["title"] as! String
body = plist["body"] as! String
author = plist["author"] as! String
favorite = plist["favorite"] as! Bool
creationDate = plist["creationDate"] as! Date
id = plist["id"] as! UUID
然后我有这个存储控制器:
class StorageController
fileprivate let documentsDirectoryURL = FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)
.first!
fileprivate var notesFileURL: URL
return documentsDirectoryURL
.appendingPathComponent("Notes")
.appendingPathExtension("plist")
func save(_ notes: [Reflection])
let notesPlist = notes.map $0.plistRepresentation as NSArray
notesPlist.write(to: notesFileURL, atomically: true)
func fetchNotes() -> [Reflection]
guard let notePlists = NSArray(contentsOf: notesFileURL) as? [[String: AnyObject]] else
print("No notes")
return []
print("Notes found")
return notePlists.map(Reflection.init(plist:))
当我调用 save()
并尝试写入 plist 时,我没有收到任何错误。但是,当我调用fetchNotes()
时,它会打印“No Notes”,这意味着使用这些内容的数组是 nil 或者它不能转换为字典。为什么会这样?
【问题讨论】:
使用init(contentsOf url: URL, error: ()) throws
会抛出error
和try/catch 怎么样?也许那里有一些信息。此外,强制转换(as ! [[String:AnyObject]]
可能会记录一些内容)。
这似乎是一个非常糟糕或过时的教程。读写属性列表的推荐方法是PropertyListSerialization
——它提供了良好的错误处理——对象值是Any
而不是AnyObject
。在 Swift 4 中,您甚至可以使用Codable
协议和PropertyListEn-/Decoder
,这会将结构中的代码减少到属性声明行。
@vadian 会调查的。遵循 Matteo Manferdini 制作专业 iOS 应用程序的终极课程。好像很更新了……
属性列表字典的类型 [String:AnyObject]
在 Swift 3+ 中不合适。所有属性列表类型都是值类型 (Any
)。这也避免了丑陋的桥梁投射到AnyObject
【参考方案1】:
UUID
不是属性列表的有效元素。您需要将其作为字符串存储在属性列表中,例如
“id”: id.uuidString as AnyObject
然后像这样转换回来:
id = UUID(uuidString: plist[“id”] as! String)!
【讨论】:
以上是关于为啥这个 plist 读/写失败?的主要内容,如果未能解决你的问题,请参考以下文章
fread()函数第一次读取成功,但第二次读取失败,为啥为啥为啥,