在 Swift 4.2 Xcode 10 中使用动作扩展从 Safari 共享 PDF 文件失败

Posted

技术标签:

【中文标题】在 Swift 4.2 Xcode 10 中使用动作扩展从 Safari 共享 PDF 文件失败【英文标题】:Sharing PDF file from Safari with Action Extension failing in Swift 4.2 Xcode 10 【发布时间】:2018-09-23 02:26:04 【问题描述】:

我正在编写一个启用了“应用程序组”功能的应用程序。此应用程序中的操作扩展对 PDF 文件开放,并且在 Safari 中加载的网页以阅读器模式打开然后转换为 PDF 时可用。

简而言之,该应用程序可以接收从 Safari 转换为 PDF 文件的网页。在升级到 Swift 4.2 之前它工作正常。自从下载 Xcode 10 后,它就停止工作并出现以下错误:

(Error Domain=NSItemProviderErrorDomain Code=-1000 "Cannot load 
representation of type com.adobe.pdf"  UserInfo   
NSLocalizedDescription=Cannot load representation of type 
com.adobe.pdf, NSUnderlyingError=0x600002dd9a70 Error
Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo=    
NSLocalizedDescription=Cannot issue a sandbox extension for file  
"/Users/xxx/Library/Developer/CoreSimulator/Devices/FE5463C2-FAA3-
41A9938B-C1C234EA966A/data"/Containers/Data/Application/B6FB42C6-B4E3-
46D8-B9F95856FF88F0B6/tmp//Safari - Sep 22, 2018 at 10:00 PM.pdf": 
Invalid argument)`

任何人都可以对正在发生的事情有所了解吗?应用程序及其操作扩展都属于同一个应用程序组。动作扩展在 info.plist 中有以下条目:

<dict>
  <key>NSExtensionAttributes</key>
  <dict>
  <key>NSExtensionActivationRule</key>
  <string>
                SUBQUERY (
                extensionItems,
                $extensionItem,
                SUBQUERY (
                $extensionItem.attachments,
                $attachment,
                ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf" ||
                ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.file-url"
                ).@count == $extensionItem.attachments.@count
                ).@count == 1
            </string>
  </dict>
  <key>NSExtensionMainStoryboard</key>
  <string>MainInterface</string>
  <key>NSExtensionPointIdentifier</key>
  <string>com.apple.ui-services</string>
  </dict>

【问题讨论】:

你有什么解决办法吗? 这个问题还没有解决办法.. 我做到了,让我解释一下 【参考方案1】:

看起来这只是 Xcode 10 iOS 12 Simulator 中的错误。

真正的 ios 12 设备上的错误为零,并且共享扩展在 iOS 11 和 iOS 12 设备上都有效。

我在我们的项目中遇到了这个问题。共享扩展在 iOS 12 模拟器下停止工作,但在 Xcode 10 的 iOS 11 模拟器下仍然可以工作。

itemProvider.loadItem(forTypeIdentifier: typeIdentifier, options: nil)  secureCoding, error in

我花了半天多的时间根据文档尝试不同的参数: https://developer.apple.com/documentation/foundation/nsitemprovider/completionhandler

没有任何帮助 - iOS 12 模拟器下的“NSItemProvider 的 loadItem”总是同样的错误:

"Cannot load representation of type public.jpeg" "Invalid argument"

Error Domain=NSItemProviderErrorDomain Code=-1000 "无法加载 public.jpeg 类型的表示" UserInfo=NSLocalizedDescription=无法加载 public.jpeg 类型的表示,NSUnderlyingError=0x6000005e1fe0 Error Domain=NSPOSIXErrorDomain Code=22 "Invalid argument" UserInfo=NSLocalizedDescription=无法为文件“/Users/user/Library/Developer/CoreSimulator/Devices/4771D8A8-E366-43CB-8A2E-7FF397E4CF6A/data/Media/PhotoData/OutgoingTemp/82644FB8-E3B8-45DE-发出沙盒扩展A0BF-563DF597872D/IMG_0003.JPG": 参数无效

但后来,我决定在 iOS 12 下的真机上进行检查。

一切都在设备上完美运行!

【讨论】:

【参考方案2】:

对我有用的解决方案是 iOS 在 iOS12 中停止了这种支持,所以我做了什么来解决这个问题。早些时候,我为此方法 loadItemForTypeIdentifier 使用了这个完成处理程序

completionHandler:^(id &lt;NSSecureCoding&gt; urlItem, NSError *error)

completionHandler 块的第一个参数的类型信息应设置为预期类型的​​类。例如,在请求文本数据时,可以将第一个参数的类型设置为 NSString 或 NSAttributedString。项目提供者可以将数据执行简单的类型转换为您指定的类,例如从 NSURL 到 NSData 或 NSFileWrapper,或从 NSData 到 UIImage(在 iOS 中)或 NSImage(在 macOS 中)。如果无法检索数据或将数据强制到指定的类,则会将错误传递给完成块。

- (void)getFilelist :(NSItemProvider *)itemProvider
 setPublicIdentifier:(NSString *)indentifier
                    :(void (^)(void))complete 

    [itemProvider loadItemForTypeIdentifier:indentifier options:nil completionHandler:^(NSURL *  _Nullable item, NSError * _Null_unspecified error) 
        dispatch_async(dispatch_get_main_queue(), ^
            NSURL *selectURl = (NSURL*)item;
            if ([[selectURl pathExtension] isEqualToString:@"pdf"] || [[selectURl pathExtension] isEqualToString:@"xlsx"] || [[selectURl pathExtension] isEqualToString:@"csv"]) 
                int randomID = arc4random() % 9000 + 1000;
                NSString *filename = [[(NSURL*)item path] lastPathComponent];
                if ([filename isEqualToString:@"FullSizeRender.jpg"]) 
                    filename = [NSString stringWithFormat:@"MD%d.jpg",randomID];
                
                [_items addObject:selectURl.absoluteString];
                complete();
            
        );
    ];

这样称呼

    for (NSItemProvider *itemProvider in item.attachments) 

            if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeText]) 
                [self getFilelist:itemProvider
                    setPublicIdentifier:(NSString *)kUTTypeText
                                       :^
                                           openFile(self, i, totalnt);
                                       ];
            

            if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypePDF]) 
                [self getFilelist:itemProvider
                  setPublicIdentifier:(NSString *)kUTTypePDF
                                     :^
                                         openFile(self, i, totalnt);
                                     ];
            

            if([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeSpreadsheet]) 
                [self getFilelist:itemProvider
                  setPublicIdentifier:(NSString *)kUTTypeSpreadsheet
                                     :^
                                         openFile(self, i, totalnt);
                                     ];
            

    

【讨论】:

什么是_mPhotos 已编辑答案请检查 这没有任何意义 - 你的 -getFileList:setPublicIdentifier: 方法的关键区别,你没有展示它是如何工作的 抱歉没找到你? 而不是 _mPhotos 使用 self 并将该方法粘贴到您的课程中,它对我有用

以上是关于在 Swift 4.2 Xcode 10 中使用动作扩展从 Safari 共享 PDF 文件失败的主要内容,如果未能解决你的问题,请参考以下文章

Clang:错误:链接器命令失败,退出代码 1(使用 -v 查看调用)Xcode 10、Xcode 10.1 Beta、Swift 4.2

Swift 4.2 新特性(译)

Firebase Deeplink 不触发应用程序:continueUserActivity:restorationHandler,Swift 4.2 Xcode10。

Xcode 10, Swift 4.2及iOS 12升级适配

是否可以将Swift 4.1添加到Xcode 10中

音频未播放 Xcode 10.1 Swift 4