我正在使用
NSPasteboard
对象的属性列表。属性列表是Dictionary
,形式如下:
var source: Dictionary<String, Any> = ["value": 1, "text": "Text"]
上面的代码运行良好。
我想要的是这个:
var source: Dictionary<CustomKeySourceType, Any> = [.value: 1, .text: "Text"]
我尝试构建这样的解决方案:
class KeySource {
struct Key : Hashable, Equatable, RawRepresentable {
var rawValue: String
static let a = KeySource.Key(rawValue: "a")
static let b = KeySource.Key(rawValue: "b")
static let c = KeySource.Key(rawValue: "c")
public init(_ rawValue: String){
self.rawValue = rawValue
}
public init(rawValue: String){
self.rawValue = rawValue
}
}
}
...
var source: Dictionary<KeySource.Key, Any> = [.a: "a", .b: 1, .c: 3.33]
它编译代码很好,但在运行时出现错误:
var pbd = NSPasteboardItem(pasteboardPropertyList: source, ofType: .experimental)
...*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not write property list with invalid format to the pasteboard. The object contains non-property list types: __SwiftValue'...
在代码中显式使用属性列表允许的类型会失败,并出现相同的错误消息。
var source: Dictionary<KeySource.Key, Any> = [.a: NSString("a"), .b: NSNumber(1), .c: NSNumber(3.33)]
NSDictionary
替代没有积极效果:
var source: NSDictionary = [KeySource.Key.a: NSString("a"), KeySource.Key.b: NSNumber(1), KeySource.Key.c: NSNumber(3.33)]
它会产生相同的运行时错误。
使其工作的唯一方法是返回到
String
键类型:
var source: Dictionary<String, Any> = [KeySource.Key.a.rawValue: NSString("a"), KeySource.Key.b.rawValue: NSNumber(1), KeySource.Key.c.rawValue: NSNumber(3.33)]
这个解决方案需要更轻。我想要简单地写出按键,例如
.a
、.b
和 .c
形式。
请帮助我建立正确的密钥源!
Xcode 12.4
部署目标10.15
你需要传递一个属性列表兼容字典,否则你会看到失败:
属性列表本身就是一个数组或字典,仅包含 NSData、NSString、NSArray、NSDictionary、NSDate 和 NSNumber 对象。
不过,从你的高级词典中创建一个并不困难:
extension Dictionary where Key: RawRepresentable, Key.RawValue == String {
var rawKeys: [Key.RawValue: Value] {
reduce(into: [:]) { $0[$1.key.rawValue] = $1.value }
}
}
借助上述扩展程序,您可以在调用站点转换词典:
NSPasteboardItem(pasteboardPropertyList: source.rawKeys, ofType: .experimental)
请注意,您仍然需要保证值的有效性,以确保它们符合正确列出的允许值。