NSUserDefaultsController:“尝试设置一个非财产清单对象...作为一个关键NS

2019-10-29 08:13发布

我试图使用NSUserDefaultsController在我斯威夫特的MacOS应用程序来实现Preferences窗口。

一个的我需要坚持的设置是预设的阵列,由下面的类定义为:

class Preset: NSObject {
    var name = "abc"
    var value = 123

    override init() {
        super.init()
    }
}

因此,我需要坚持类型的变量[Presets] 。 在我的首选项窗口的可视化表示是NSTableView ,绑定到一个NSArrayController

我跟着这个教程设置我的绑定。 当运行应用程序,并尝试添加新的预设(通过单击+按钮),我收到以下错误:

[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

我试图实现CodableNSCoding协议,但错误依然存在。

从搜索的堆栈溢出类似的问题(如本或本 ),它出现在解决方案将涉及NSKeyedArchiverNSKeyedUnarchiver 。 这似乎很简单做,如果你手动触发加载和保存。 不幸的是我不知道如何使用这些类沿NSUserDefaultsController

Answer 1:

我通过继承解决了这个问题NSArrayController如下(见麦高乐的留言我的其他问题 ,这是最后缺少的一块拼图,使这个通用):

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: “Attempt to set a non-property-list object … as an NSUserDefaults/CFPreferences value for key …”