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

macOS SwiftUI跨视图拖拽String时NSItemProvider加载NSString报错如何解决

问题结论

这个是macOS平台NSItemProvider针对字符串类型处理的已知系统Bug,不是你的实现逻辑问题。相同代码在iOS/iPadOS可正常运行,是因为两个平台对NSString的类型桥接和ItemProvider加载逻辑实现不一致,URL类型没有出现问题是因为该类型的加载适配在两个平台是统一的。

可行解决方案

方案1:通过UTType标识符加载数据再转字符串(推荐,支持跨App拖拽字符串)

替换onDrop中的loadObject(ofClass:)方法,改用底层的loadItem(forTypeIdentifier:options:)接口解析内容,代码如下:

ViewB()
    .onDrop(of: [.plainText], isTargeted: nil, perform: { providers, location in
        guard let provider = providers.first, 
              provider.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) else {
            return false
        }
        provider.loadItem(forTypeIdentifier: UTType.plainText.identifier, options: nil) { item, error in
            DispatchQueue.main.async {
                // macOS下拖拽字符串会返回Data或String两种类型,做兼容判断即可
                var droppedText: String?
                if let textData = item as? Data {
                    droppedText = String(data: textData, encoding: .utf8)
                } else if let rawText = item as? String {
                    droppedText = rawText
                }
                if let text = droppedText {
                    print("Dropped: \(text)")
                    // 后续业务逻辑
                } else {
                    print("Parse error: \(error?.localizedDescription ?? "unknown")")
                }
            }
        }
        return true
    })

方案2:自定义UTType传递字符串(仅适用App内部拖拽场景)

如果你的拖拽场景仅在App内部使用,不需要和其他App交互,可以自定义UTType来传递字符串,绕开系统对plainText类型的加载bug:

  • 在项目Info.plist中注册自定义UTType
  • 拖拽时用自定义UTType初始化NSItemProvider
  • Drop时按自定义UTType加载即可,逻辑和URL类型的拖拽完全一致

内容的提问来源于stack exchange,提问作者Marcos Tanaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:45:06