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

iOS17 Safari复制URL后NSItemProvider.loadItem解析异常如何处理?

解决iOS 17 Safari复制URL后的解析问题

问题分析

iOS 17中Safari复制URL时,通过UTType.url获取的粘贴项不再是单纯的URL数据,而是封装了URL、页面标题等信息的二进制plist。你的代码先尝试解析plist但未命中正确逻辑,转而用URL(dataRepresentation:)处理,导致把整个plist字节流当成URL数据,出现乱码的plist内容。

解决方案

调整解析逻辑优先级:先尝试直接获取URL类型的返回值;如果拿到的是Data,优先解析为plist字典并提取URL字段;最后保留兜底的URL解析逻辑。

修改后的代码

let item = try await itemProvider.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil)

// 优先尝试直接获取URL对象(iOS 17部分场景会直接返回)
if let url = item as? URL {
    print("直接获取到URL: \(url.absoluteString)")
} 
// 处理二进制plist格式的Data
else if let data = item as? Data {
    do {
        // 解析二进制plist,指定兼容可变容器的选项
        if let plist = try PropertyListSerialization.propertyList(from: data, options: [.mutableContainers], format: nil) as? [String: Any] {
            // 从plist字典中提取URL字段(iOS 17中键通常为"NSURL")
            if let urlString = plist["NSURL"] as? String, let url = URL(string: urlString) {
                print("从plist解析出URL: \(url.absoluteString)")
                // 可选:提取页面标题
                if let title = plist["NSTitle"] as? String {
                    print("页面标题: \(title)")
                }
            }
        } 
        // 兜底逻辑:兼容旧系统或特殊场景下的直接URL数据
        else if let url = URL(dataRepresentation: data, relativeTo: nil) {
            print("兜底解析URL: \(url.absoluteString)")
        }
    } catch {
        print("解析失败: \(error.localizedDescription)")
    }
}

关键说明

  • iOS 17中loadItem(forTypeIdentifier:UTType.url.identifier)在部分场景下会直接返回URL实例,因此优先判断该情况可以简化处理。
  • 当返回Data时,该数据是二进制plist格式,解析后的字典通常包含NSURL(存储URL字符串)和NSTitle(存储页面标题)字段,可根据实际测试调整键名。
  • 保留兜底的URL(dataRepresentation:)逻辑,确保兼容旧系统或其他应用复制的纯URL数据格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 09:45:57