NSItemProvider loadItem 方法 returns _NSItemProviderSandboxedResource 而不是 URL
NSItemProvider loadItem method returns _NSItemProviderSandboxedResource instead of URL
在我开发的其中一个应用程序中,我使用共享扩展来导入电子钱包通行证 (PKPass)。
在 iOS 13(包括最新的 beta 8)上,当从 iOS 邮件应用程序中调用共享扩展时,该扩展没有接收到预期格式的数据(URL).
这是分享扩展的 ShareViewController 的相关片段:
if let inputItems = self.extensionContext?.inputItems,
let inputItem = inputItems.first as? NSExtensionItem,
let attachments = inputItem.attachments,
let attachment = attachments.first,
attachment.hasItemConformingToTypeIdentifier("com.apple.pkpass" as String){
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) { data, error in
print ("data: \(String(describing: data))")
}
在 iOS 12(最新版本)上,这也适用于 iOS 邮件应用程序中的附件(除了例如文件应用程序中的文件);数据包含一个可选的 URL。
上面的打印语句在控制台显示如下:
data: Optional(file:///var/mobile/Library/Mail/8EF174CF-68B9-414E-A166-D04C9DBE020E/INBOX.imapmbox/Attachments/13846/2/Attachment-1.pkpass)
在 iOS 13(测试版 8)上,在 iOS 邮件应用程序中,数据包含一个可选的 _NSItemProviderSandboxedResource。
上面的打印语句在控制台显示如下:
data: Optional(<_NSItemProviderSandboxedResource: 0x2839aa9e0>)
这似乎只影响邮件应用程序。在文件应用程序中,数据如预期的那样保存 URL.
这是一个错误(实际上我已经在 beta 4 中使用反馈助手报告过这个问题)还是 iOS 13 引入的一些新的安全功能?在这种情况下,如何访问附件的 url/data?
我遇到了同样的错误,看来我现在找到了解决方案
尝试使用 attachments.last
而不是 .first
看起来像 Apple returns 多种邮件应用附件类型。
刚刚找到解决此问题的方法。
在iOS13之前调用
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) data, error in
数据也可以向下转换为 URL,如下所示
if let pkPassURL = data as? URL
如上述问题所述,在 iOS 13 中,这不再可能了。
相反,现在需要使用 "public.file-url" 作为类型标识符来调用 loadItem:
attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in
在 PKPass 项目的具体情况下,我在分享它们时注意到
- 来自电子钱包应用的附件将仅符合 "com.apple.pkpass"
- 来自例如邮件应用程序附件将同时符合 "com.apple.pkpass" 和 "public.file-url"
所以下面的代码可以用来处理这两种情况:
if let inputItems = self.extensionContext?.inputItems,
let inputItem = inputItems.first as? NSExtensionItem,
let attachments = inputItem.attachments,
let attachment = attachments.first,
attachment.hasItemConformingToTypeIdentifier("com.apple.pkpass" as String) {
if attachment.hasItemConformingToTypeIdentifier("public.file-url" as String) {
// extension is being called e.g. from Mail app
attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in
if let sourcePKPassURL = data as? URL {
//handle url here
}
}
} else {
// extension is being called from Wallet app
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) { (data, error) in
if let pkPassData = data as? Data,
let pkPass = try? PKPass(data: pkPassData) {
// handle pkPass here
}
}
}
}
这适用于 iOS 12 和 iOS 13。
自 iOS13 以来,我在 Apple Mail 附件中遇到了同样的问题。另外,之前检查 UTI 并加载该类型在下面的代码中不起作用。
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
if let itemProvider = item.attachments?.first {
let type = itemProvider.registeredTypeIdentifiers
let uti = type.first!
if itemProvider.hasItemConformingToTypeIdentifier(uti) {
itemProvider.loadItem(forTypeIdentifier:uti, options: nil, completionHandler: { (item, error) -> Void in
print(item) //<_NSItemProviderSandboxedResource: 0x2839aa9e0>
})
}
}}
在我开发的其中一个应用程序中,我使用共享扩展来导入电子钱包通行证 (PKPass)。
在 iOS 13(包括最新的 beta 8)上,当从 iOS 邮件应用程序中调用共享扩展时,该扩展没有接收到预期格式的数据(URL).
这是分享扩展的 ShareViewController 的相关片段:
if let inputItems = self.extensionContext?.inputItems,
let inputItem = inputItems.first as? NSExtensionItem,
let attachments = inputItem.attachments,
let attachment = attachments.first,
attachment.hasItemConformingToTypeIdentifier("com.apple.pkpass" as String){
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) { data, error in
print ("data: \(String(describing: data))")
}
在 iOS 12(最新版本)上,这也适用于 iOS 邮件应用程序中的附件(除了例如文件应用程序中的文件);数据包含一个可选的 URL。 上面的打印语句在控制台显示如下:
data: Optional(file:///var/mobile/Library/Mail/8EF174CF-68B9-414E-A166-D04C9DBE020E/INBOX.imapmbox/Attachments/13846/2/Attachment-1.pkpass)
在 iOS 13(测试版 8)上,在 iOS 邮件应用程序中,数据包含一个可选的 _NSItemProviderSandboxedResource。 上面的打印语句在控制台显示如下:
data: Optional(<_NSItemProviderSandboxedResource: 0x2839aa9e0>)
这似乎只影响邮件应用程序。在文件应用程序中,数据如预期的那样保存 URL.
这是一个错误(实际上我已经在 beta 4 中使用反馈助手报告过这个问题)还是 iOS 13 引入的一些新的安全功能?在这种情况下,如何访问附件的 url/data?
我遇到了同样的错误,看来我现在找到了解决方案
尝试使用 attachments.last
而不是 .first
看起来像 Apple returns 多种邮件应用附件类型。
刚刚找到解决此问题的方法。
在iOS13之前调用
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) data, error in
数据也可以向下转换为 URL,如下所示
if let pkPassURL = data as? URL
如上述问题所述,在 iOS 13 中,这不再可能了。
相反,现在需要使用 "public.file-url" 作为类型标识符来调用 loadItem:
attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in
在 PKPass 项目的具体情况下,我在分享它们时注意到
- 来自电子钱包应用的附件将仅符合 "com.apple.pkpass"
- 来自例如邮件应用程序附件将同时符合 "com.apple.pkpass" 和 "public.file-url"
所以下面的代码可以用来处理这两种情况:
if let inputItems = self.extensionContext?.inputItems,
let inputItem = inputItems.first as? NSExtensionItem,
let attachments = inputItem.attachments,
let attachment = attachments.first,
attachment.hasItemConformingToTypeIdentifier("com.apple.pkpass" as String) {
if attachment.hasItemConformingToTypeIdentifier("public.file-url" as String) {
// extension is being called e.g. from Mail app
attachment.loadItem(forTypeIdentifier: "public.file-url" as String, options: nil) { (data, error) in
if let sourcePKPassURL = data as? URL {
//handle url here
}
}
} else {
// extension is being called from Wallet app
attachment.loadItem(forTypeIdentifier: "com.apple.pkpass" as String, options: nil) { (data, error) in
if let pkPassData = data as? Data,
let pkPass = try? PKPass(data: pkPassData) {
// handle pkPass here
}
}
}
}
这适用于 iOS 12 和 iOS 13。
自 iOS13 以来,我在 Apple Mail 附件中遇到了同样的问题。另外,之前检查 UTI 并加载该类型在下面的代码中不起作用。
if let item = extensionContext?.inputItems.first as? NSExtensionItem {
if let itemProvider = item.attachments?.first {
let type = itemProvider.registeredTypeIdentifiers
let uti = type.first!
if itemProvider.hasItemConformingToTypeIdentifier(uti) {
itemProvider.loadItem(forTypeIdentifier:uti, options: nil, completionHandler: { (item, error) -> Void in
print(item) //<_NSItemProviderSandboxedResource: 0x2839aa9e0>
})
}
}}