You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

简化NSPasteboard属性列表键值对的自定义键实现问题

解决NSPasteboard自定义字典键的运行时错误问题

问题根源

NSPasteboard的属性列表要求字典键必须是属性列表允许的类型(如NSString),而Swift自定义类型(即使遵循Hashable/RawRepresentable)作为字典键时,桥接到Objective-C会被包装成__SwiftValue对象,不符合属性列表格式要求,因此触发运行时错误。

可行解决方案

方案1:自定义结构体封装,保持简洁写法

通过结构体封装底层的[String: Any]字典,重载下标使用自定义键,同时提供转换为合规字典的接口:

// 定义自定义键枚举
enum CustomKey: String {
    case value
    case text
}

// 封装粘贴板数据的结构体
struct PasteboardData {
    private var storage: [String: Any] = [:]
    
    // 重载下标,使用自定义键读写
    subscript(key: CustomKey) -> Any? {
        get { storage[key.rawValue] }
        set { storage[key.rawValue] = newValue }
    }
    
    // 输出符合要求的属性列表字典
    var propertyList: [String: Any] { storage }
}

使用示例:

var source = PasteboardData()
source[.value] = 1
source[.text] = "Text"

// 传入合规的字典给NSPasteboardItem
let pbd = NSPasteboardItem(pasteboardPropertyList: source.propertyList, ofType: .experimental)

方案2:扩展NSPasteboardItem添加便捷初始化

直接扩展系统类,新增接受自定义键字典的初始化方法,内部自动转换为字符串键字典:

enum CustomKey: String {
    case value
    case text
}

extension NSPasteboardItem {
    convenience init(customPropertyList: [CustomKey: Any], ofType type: NSPasteboard.PasteboardType) {
        // 将自定义键字典转换为字符串键字典
        let convertedDict = customPropertyList.reduce(into: [String: Any]()) { result, pair in
            result[pair.key.rawValue] = pair.value
        }
        self.init(pasteboardPropertyList: convertedDict, ofType: type)
    }
}

使用示例:

let source: [CustomKey: Any] = [.value: 1, .text: "Text"]
let pbd = NSPasteboardItem(customPropertyList: source, ofType: .experimental)

注意事项

  • 确保字典中的值也是属性列表允许的类型(如NSString、NSNumber、NSArray等),Swift基础类型会自动桥接,无需手动转换。
  • 两种方案都保留了.value、.text的简洁写法,同时规避了自定义键类型的桥接问题。

内容的提问来源于stack exchange,提问作者Ruben Kazumov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:23:13