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