我正在尝试使用NSUserDefaultsController
在我的Swift macOS应用中实现“偏好设置”窗口。
我需要保留的设置之一是一组预设,如以下类所定义:
class Preset: NSObject {
var name = "abc"
var value = 123
override init() {
super.init()
}
}
因此,我需要保留类型[Presets]
的变量。我的“偏好设置”窗口中的外观是NSTableView
,绑定到NSArrayController
。
我遵循了this教程来设置绑定。运行应用程序并尝试添加新的预设时(通过单击+
按钮),出现以下错误:
[User Defaults] Attempt to set a non-property-list object (...) as an NSUserDefaults/CFPreferences value for key presets
[General] Attempt to insert non-property list object (...) for key presets
我尝试实现Codable
和NSCoding
协议,但是错误仍然存在。
通过在堆栈溢出中搜索类似的问题(例如this或this),看来解决方案将涉及NSKeyedArchiver
和NSKeyedUnarchiver
。如果您手动触发加载和保存,那么这看起来就足够简单了。不幸的是,我没有看到如何将这些类与NSUserDefaultsController
一起使用。
答案 0 :(得分:0)
我通过如下子类化NSArrayController
解决了这个问题(请参见Hamish对my other question的评论,这是使该泛型成为难题的最后一个遗漏的部分):
extension Encodable {
fileprivate func encode(to container: inout SingleValueEncodingContainer) throws {
try container.encode(self)
}
}
struct AnyEncodable: Encodable {
var value: Encodable
init(_ value: Encodable) {
self.value = value
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try value.encode(to: &container)
}
}
class NSEncodableArrayController: NSArrayController {
override func addObject(_ object: Any) {
let data = try! PropertyListEncoder().encode(AnyEncodable(object as! Encodable))
let any = try! PropertyListSerialization.propertyList(from: data, options: [], format: nil)
super.addObject(any)
}
}