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
相关产品推荐
相关产品推荐

