在我开发的一个应用程序中,我使用共享扩展来导入钱包通行证(PKPass)。
在 iOS 13(包括最新的测试版 8)上,从 iOS Mail 应用程序中调用共享扩展时,扩展程序未接收预期格式 (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 Mail应用程序中的附件(此外,例如文件应用程序中的文件);数据保存一个可选的URL。 上面的 print 语句在控制台中如下所示:
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。 上面的 print 语句在控制台中如下所示:
data: Optional(<_NSItemProviderSandboxedResource: 0x2839aa9e0>)
这似乎只影响邮件应用程序。在"文件"应用中,数据按预期保存一个 URL。
这是一个错误(实际上我已经在beta 4上使用反馈助手报告了这个问题)还是iOS 13引入的一些新的安全功能?在这种情况下,如何访问附件的 URL/数据?
刚刚找到了这个问题的解决方案。
在 iOS 13 之前通话时
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。
自iOS 13以来,我在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>
})
}
}}
我遇到了同样的错误,看起来我现在得到了解决方案
尝试使用attachments.last
而不是.first
看起来苹果为邮件应用程序附件返回多种类型。