NSUserDefaultsController:"Attempt to set a non-property-list object ... as an NSUserDefaults/CFPreferences value for key ..."
NSUserDefaultsController: "Attempt to set a non-property-list object ... as an NSUserDefaults/CFPreferences value for key ..."
我正在尝试使用 NSUserDefaultsController
在我的 Swift macOS 应用程序中实现首选项 window。
我需要保留的设置之一是一组预设,定义如下 class:
class Preset: NSObject {
var name = "abc"
var value = 123
override init() {
super.init()
}
}
因此,我需要持久化一个[Presets]
类型的变量。我的首选项 window 中的视觉表示是 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
协议,但错误仍然存在。
通过在 Stack Overflow 中搜索类似问题(例如 or this),似乎解决方案涉及 NSKeyedArchiver
和 NSKeyedUnarchiver
。如果您手动触发加载和保存,这看起来很简单。不幸的是,我不知道如何将这些 classes 与 NSUserDefaultsController
.
一起使用
我通过子类化 NSArrayController
解决了这个问题,如下所示(参见 Hamish 对 的评论,这是使这个通用的最后一个缺失的拼图):
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)
}
}
我正在尝试使用 NSUserDefaultsController
在我的 Swift macOS 应用程序中实现首选项 window。
我需要保留的设置之一是一组预设,定义如下 class:
class Preset: NSObject {
var name = "abc"
var value = 123
override init() {
super.init()
}
}
因此,我需要持久化一个[Presets]
类型的变量。我的首选项 window 中的视觉表示是 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
协议,但错误仍然存在。
通过在 Stack Overflow 中搜索类似问题(例如 NSKeyedArchiver
和 NSKeyedUnarchiver
。如果您手动触发加载和保存,这看起来很简单。不幸的是,我不知道如何将这些 classes 与 NSUserDefaultsController
.
我通过子类化 NSArrayController
解决了这个问题,如下所示(参见 Hamish 对
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)
}
}