iOS 分享扩展 - 发送大视频

Posted

技术标签:

【中文标题】iOS 分享扩展 - 发送大视频【英文标题】:iOS Share Extension - Sending Large Video 【发布时间】:2018-03-29 19:57:27 【问题描述】:

所以我尝试发送一个大视频文件(超过 100 mb),每当我使用 dataWithContentsOfURL 访问视频文件时,扩展程序都会终止。这适用于较小的文件。

我应该如何解决它?

if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie])
            [itemProvider loadItemForTypeIdentifier:(NSString *)kUTTypeMovie options:nil completionHandler:urlHandler];





NSItemProviderCompletionHandler urlHandler = ^(NSURL *item, NSError *error) 

  if ([itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeVideo] | [itemProvider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeMovie])
  
        NSData *fileData = [NSData dataWithContentsOfURL:item]

        // ----> fileData WORKS for small files.
        // ----> for large files, extension QUITS - without any trace - and control does not proceed after this. This may be due to memory pressure?  

        [_shareExtensionActionsManager sendTextMessage:contentText attachmentData:fileData attachmentName:@"video-1" toChatEntity:_selectedItem completion:^(BOOL success) 
               
                 [self.extensionContext completeRequestReturningItems:nil completionHandler:^(BOOL expired) 
    exit(0);
];
         ];  
    
;

【问题讨论】:

您是否尝试过使用 inputStream 以增量方式读取文件?(developer.apple.com/documentation/foundation/nsinputstream/…) @DharmeshTarapore 你还是把它载入内存了吗? 你是对的;我没有注意到这是一个应用程序扩展。我添加了一个可能有帮助的答案。我也认为你错过了一个'|'在你的第二个 hasItemConformingToTypeIdentifier 比较中,除非这是故意的。 【参考方案1】:

来自app extension docs:

用户往往会在完成应用扩展程序中的任务后立即返回宿主应用。如果任务涉及可能很长的上传或下载,您需要确保它可以在您的扩展程序终止后完成。

在你的应用扩展调用 completeRequestReturningItems:completionHandler: 告诉宿主应用它的请求完成后,系统可以随时终止你的扩展。

您将需要使用 NSURLSession 创建一个启动后台任务的 URL 会话。

如果后台任务完成时您的扩展程序没有运行,系统将在后台启动您的包含应用程序并在您的 AppDelegate 中调用application:handleEventsForBackgroundURLSession:completionHandler:

您还需要设置一个shared container,您的扩展程序和包含的应用程序都可以访问该shared container。为此,您需要使用 NSURLSessionConfiguration 的 sharedContainerIdentifier 属性来指定容器的标识符,以便以后可以访问它。

以下是文档中的一个示例,展示了如何实现这一目标:

NSURLSession *mySession = [self configureMySession];
   NSURL *url = [NSURL URLWithString:@"http://www.example.com/LargeFile.zip"];
   NSURLSessionTask *myTask = [mySession downloadTaskWithURL:url];
   [myTask resume];

- (NSURLSession *) configureMySession 
    if (!mySession) 
        NSURLSessionConfiguration* config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@“com.mycompany.myapp.backgroundsession”];
// To access the shared container you set up, use the sharedContainerIdentifier property on your configuration object.
config.sharedContainerIdentifier = @“com.mycompany.myappgroupidentifier”;
        mySession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
    
    return mySession;

这里有一个related resource,可能会有所帮助。

【讨论】:

如果你不使用 NSURLSession... :/ 恐怕这是唯一的选择,没有重新设计扩展的功能。 100MB 相当大,特别是对于互联网连接速度较慢的用户而言,并且一般用户会期望共享操作很快完成。可能还有其他方法,但如果没有关于您的应用和扩展程序的更多上下文,很难说。不过祝你好运! 我找到了答案。这是原生 ios 限制,尤其是在后台。如果您需要上传或流式传输,则必须创建自定义视图控制器而不是原生共享表,并仅在上传完成后将其关闭。【参考方案2】:

应用程序扩展可能没有此任务的内存容量。

运行应用扩展的内存限制明显低于前台应用的内存限制。在这两个平台上,系统可能会主动终止扩展,因为用户希望在宿主应用程序中返回他们的主要目标。某些扩展的内存限制可能比其他扩展低:例如,小部件必须特别高效,因为用户可能会同时打开多个小部件。

https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionCreation.html#//apple_ref/doc/uid/TP40014214-CH5-SW1

【讨论】:

以上是关于iOS 分享扩展 - 发送大视频的主要内容,如果未能解决你的问题,请参考以下文章

iOS 无法使用 UIDocumentInteractionController 将视频分享到 Whatsapp

iOS版发送视频(屏幕共享)的数据包在后台UDP连接

为啥共享视频只发送到其他一些应用程序?

如何在广播上传扩展(iOS)中实现上传?

微信分享视频不能大于25M?其实这样简单操作几步,就能轻松发送

IOS技术分享| 在iOS WebRTC 中添加美颜滤镜