通过UIActivityViewController将图像/视频分享到其他应用程序在iOS

时间:2016-07-27 12:41:46

标签: ios objective-c share uiactivityviewcontroller uiactivity

我尝试使用UIActivityViewController向其他应用(例如FB,WhatsApp)分享一些图片和视频。我已经对UIActivityItemProvider进行了细分,并且在调用-(id)item方法时,我正在处理图片/视频并保存在文档目录中。然后我将文件路径返回为NSURLs。我的问题是我无法找到同时发送多个文件网址的方法。

以下是我从 - (id)item方法返回网址的方法;

  1. 作为NSArrayNSURL个对象。什么都不行。当目标应用弹出来时,它总是空的。
  2. 作为NSDictionaryNSURL个对象是值,键可以是任何东西。问题:目标应用程序弹出窗口显示所有项目,但是TWICE!我经常试用字典,但无法找到解决这个问题的方法。
  3. 只需从NSURL方法返回-(id)item对象,就可以正常处理单个文件。但是,我必须分享多个项目。数组不起作用,字典正在复制共享项目。

    有人可以告诉我,我在这里做错了什么吗?

    更新1:

    这是我展示UIActivityViewController的方式。

    CustomItemProvider *provider = [[CustomItemProvider alloc] initWithPlaceholderItem:[UIImage imageNamed:@"ios-59.png"]];
    
    UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:@[provider] applicationActivities:nil];
    
    activityViewController.completionWithItemsHandler = ^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError)
    {
        if(completed)
        {
            NSLog(@"Activity Completed");
        }
        else
        {
            NSLog(@"Activity Cancelled");
        }
    };
    [self presentViewController:activityViewController animated:YES completion:^{}];
    

    UIActivityItemProvider实现如下所示;网址有效,并且在这些位置有图片/视频。

    @interface CustomItemProvider : UIActivityItemProvider
    
    @end
    
    @implementation CustomItemProvider
    - (id)item
    {
         NSURL *url1 = [NSURL fileURLWithPath:@"file one url"];
         NSURL *url2 = [NSURL fileURLWithPath:@"file two url"];
         NSURL *url3 = [NSURL fileURLWithPath:@"file three url"];
    
         return @{@"item1":url1, @"item2":url2, @"item3":url3};    //As NSDictionary. This causes 6 items to be shared; all files twice.
    
         //return @[url1, url2, url3];  //As NSArray
    }
    @end
    

    更新2:

    链接的问题是不同的。 我不想将文件直接发送到UIActivityViewController作为initWithActivityItems:的参数。原因是可能存在多个视频文件,这将导致内存警告和崩溃。此外,我将在将文件发送到目标应用程序之前对其进行操作(在-(id)item方法中,我在此处未显示),因此我需要UIActivityItemProvider来处理后台文件。

2 个答案:

答案 0 :(得分:1)

与其他应用分享图片: Swift 3代码 -

    let image = UIImage(named: "yourimage")
    let objectsToShare = [image]
    let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
    present(activityVC, animated: true, completion: nil)

答案 1 :(得分:0)

更新: 这种方法完全错误,在某些情况下会导致意外结果。对不起,如果这个回答误导任何人。

正确的方法是为每个要共享的项创建一个UIActivityItemProvider对象。并从相应的提供程序对象返回要共享的项目。很抱歉,我之前无法更新此答案。

大家好日子!

好的,最后我明白了。这让我很疯狂,我无法在任何地方找到任何适当的文档/答案。

解决方案是以NSItemProvider个对象作为值返回字典。相同的键可以是与其他键不同的任何键。

如果有人遇到同样的问题,请找到以下解决方案;

@interface CustomItemProvider : UIActivityItemProvider
{
     NSCondition *_condition;
     NSArray *_filesToShare;
}
@end

@implementation CustomItemProvider
- (id)item
{
    _fetchInProgress = YES; 
    //Here start fetching/processing videos/photos in ANOTHER THREAD. Once the fetching/processing is complete, set the value of _fetchInProgress to NO.

    //If you want to show progress, display progress view in MAIN THREAD here.

    [_condition lock];
    while(_fetchInProgress)
    {
        [_condition wait];
    }
    [_condition unlock];

    //Here I am assuming that the files are processed and are saved to documents/cache directory and their file-paths are in _filesToShare array.

     NSMutableDictionary *itemsDict = [NSMutableDictionary dictionaryWithCapacity:[_filesToShare count]];
     for (int i = 0; i < [_filesToShare count]; i++)
     {
         NSURL *url = [NSURL fileURLWithPath:[_filesToShare objectAtIndex:i]];
         NSItemProvider *item = [[NSItemProvider alloc] initWithContentsOfURL:url];
         [itemsDict setObject:item forKey:@(i)];
     }

     return itemsDict;
}
@end

干杯!!!