通过 UIActivityViewController 共享 images/videos 到其他应用程序在 iOS 中显示共享项目两次
Sharing images/videos to other apps through UIActivityViewController shows shared items twice in iOS
我正在尝试使用 UIActivityViewController
将一些图像和视频分享到其他应用程序(如 FB、WhatsApp)。我对 UIActivityItemProvider
进行了子分类,在调用 -(id)item
方法时,我正在处理 images/videos 并保存在文档目录中。然后我 return 将文件路径设置为 NSURLs
。我的问题是 我找不到同时发送多个文件 URL 的方法。
以下是我从 -(id)item 方法return url 采取的方法;
- 作为
NSArray
个 NSURL
个对象。不工作。当目标应用弹窗出现时,它总是空的。
- 作为
NSDictionary
,其中 NSURL
对象是值,键可以是任何东西。问题:目标应用程序弹出窗口显示所有项目,但两次!我尝试了很多字典,但找不到解决这个问题的方法。
只需 return 从 -(id)item
方法中获取一个 NSURL
对象就可以很好地处理单个文件。但是,我必须共享多个项目。数组不起作用,字典正在复制共享项。
有人可以告诉我我做错了什么吗?
更新 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 实现如下;这些 URL 有效并且在这些位置有 images/videos。
@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:
链接的问题不同。
我不想将文件作为 initWithActivityItems:
的参数直接发送到 UIActivityViewController。原因是可能有多个视频文件,这会导致内存警告和崩溃。此外,我将在将文件发送到目标应用程序之前对其进行处理(在 -(id)item
方法中,我未在此处显示),因此我需要 UIActivityItemProvider
在后台处理文件。
更新:
这种做法是完全错误的,在某些场景下会导致意想不到的结果。如果这个回答误导了大家,抱歉。
正确的做法是为每个要共享的项目创建一个 UIActivityItemProvider 对象。并且 return 要从相应的提供者对象共享的项目。对不起,我之前无法更新此答案。
大家好!
好的,我终于明白了。这让我发疯了,我在任何地方都找不到合适的 documentation/answers。
解决方案是 return 一个以 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
干杯!!!
与其他应用分享图片:
Swift3码-
let image = UIImage(named: "yourimage")
let objectsToShare = [image]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
present(activityVC, animated: true, completion: nil)
我正在尝试使用 UIActivityViewController
将一些图像和视频分享到其他应用程序(如 FB、WhatsApp)。我对 UIActivityItemProvider
进行了子分类,在调用 -(id)item
方法时,我正在处理 images/videos 并保存在文档目录中。然后我 return 将文件路径设置为 NSURLs
。我的问题是 我找不到同时发送多个文件 URL 的方法。
以下是我从 -(id)item 方法return url 采取的方法;
- 作为
NSArray
个NSURL
个对象。不工作。当目标应用弹窗出现时,它总是空的。 - 作为
NSDictionary
,其中NSURL
对象是值,键可以是任何东西。问题:目标应用程序弹出窗口显示所有项目,但两次!我尝试了很多字典,但找不到解决这个问题的方法。
只需 return 从 -(id)item
方法中获取一个 NSURL
对象就可以很好地处理单个文件。但是,我必须共享多个项目。数组不起作用,字典正在复制共享项。
有人可以告诉我我做错了什么吗?
更新 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 实现如下;这些 URL 有效并且在这些位置有 images/videos。
@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:
链接的问题不同。
我不想将文件作为 initWithActivityItems:
的参数直接发送到 UIActivityViewController。原因是可能有多个视频文件,这会导致内存警告和崩溃。此外,我将在将文件发送到目标应用程序之前对其进行处理(在 -(id)item
方法中,我未在此处显示),因此我需要 UIActivityItemProvider
在后台处理文件。
更新: 这种做法是完全错误的,在某些场景下会导致意想不到的结果。如果这个回答误导了大家,抱歉。
正确的做法是为每个要共享的项目创建一个 UIActivityItemProvider 对象。并且 return 要从相应的提供者对象共享的项目。对不起,我之前无法更新此答案。
大家好!
好的,我终于明白了。这让我发疯了,我在任何地方都找不到合适的 documentation/answers。
解决方案是 return 一个以 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
干杯!!!
与其他应用分享图片: Swift3码-
let image = UIImage(named: "yourimage")
let objectsToShare = [image]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
present(activityVC, animated: true, completion: nil)