我有一个应该能够共享多个图像的更大的应用程序。 我使用UIActivityViewController和UIActivityItemProvider实现了这个项目的异步使用(所以我只需要一次准备一个图像,而不必一次填充所有这些图像以共享它们)。
我受到启发"通过Apple Airdrop示例: AirdropSample download
然而,在使用我的应用分享时,例如9张图像(相机滚动=="保存9张图像")只有4到7张图像最终进入相机胶卷,没有任何错误信息。 如果我一遍又一遍地重复它,我会得到5张图像或6张看似随意的图像。
我不能在这里发布我的应用程序,但我修改了上面的示例,它也会随机地"失败"将所有图像传送到相机卷......
如果您下载上面的示例并用这些文件替换4个文件,则会显示问题:
APLAsyncImageViewController.h:
#import <UIKit/UIKit.h>
#import "APLAsyncImageActivityItemProvider.h"
@interface APLAsyncImageViewController : UIViewController
@end
APLAsyncImageViewController.m:
#import "APLAsyncImageViewController.h"
#import "APLProgressAlertViewController.h"
NSString * const kProgressAlertViewControllerIdentifier = @"APLProgressAlertViewController";
@interface APLAsyncImageViewController ()
@property (strong, nonatomic) UIWindow *alertWindow;
@property (strong, nonatomic) APLProgressAlertViewController *alertViewController;
@property (strong, nonatomic) UIPopoverController *activityPopover;
@property (weak, nonatomic) IBOutlet UIButton *shareImageButton;
- (IBAction)openActivitySheet:(id)sender;
@end
@implementation APLAsyncImageViewController
- (IBAction)openActivitySheet:(id)sender
{
NSMutableArray *itemArray = [[NSMutableArray alloc] init];
for( int i = 0; i < 9;i++)
{
APLAsyncImageActivityItemProvider *aiImageItemProvider = [[APLAsyncImageActivityItemProvider alloc] init];
[itemArray addObject: aiImageItemProvider];
}
//Create an activity view controller with the activity provider item. UIActivityItemProvider (AsyncImageActivityItemProvider's superclass) conforms to the UIActivityItemSource protocol
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:itemArray applicationActivities:nil];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
//iPhone, present activity view controller as is
[self presentViewController:activityViewController animated:YES completion:nil];
}
else
{
//iPad, present the view controller inside a popover
if (![self.activityPopover isPopoverVisible]) {
self.activityPopover = [[UIPopoverController alloc] initWithContentViewController:activityViewController];
[self.activityPopover presentPopoverFromRect:[self.shareImageButton frame] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
else
{
//Dismiss if the button is tapped while pop over is visible
[self.activityPopover dismissPopoverAnimated:YES];
}
}
}
@end
APLAsyncImageActivityItemProvider.h:
#import <UIKit/UIKit.h>
@interface APLAsyncImageActivityItemProvider : UIActivityItemProvider
@end
APLAsyncImageActivityItemProvider.m:
#import "APLAsyncImageActivityItemProvider.h"
#import "UIImage+Resize.h"
@implementation APLAsyncImageActivityItemProvider
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
return [[UIImage alloc] init];
}
- (id)item
{
UIImage *image = [UIImage imageNamed:@"Flower.png"];
//CGSize imageSize;
//imageSize.height = 1000;
//imageSize.width = 1000;
//image = [UIImage imageWithImage:image scaledToFitToSize:imageSize];
return image;
}
- (UIImage *)activityViewController:(UIActivityViewController *)activityViewController thumbnailImageForActivityType:(NSString *)activityType suggestedSize:(CGSize)size
{
//The filtered image is the image to display on the other side.
return [[UIImage alloc] init];
}
@end
如果您执行此类示例(使用菜单项&#34;预处理后发送图像&#34;,按&#34; SHARE&#34;按钮),它将经常或大部分无法将所有9个图像传送到相机胶卷。
如果您取消注释&#34; APLAsyncImageActivityItemProvider.m&#34;中的4行。这基本上只是缩放输出图像然后它将始终有效。
你能告诉我为什么吗?我觉得,如果我知道这个谜语的答案,我也可以修复我的应用程序。谢谢,
尼尔斯
答案 0 :(得分:1)
这个问题的原因非常简单。
应用程序可以使用有限数量的编写器线程,因此同时写入太多图像可能会因“写入忙”错误而失败。您可以通过尝试使用UIImageWriteToSavedPhotosAlbum(或相应的Asset / Photos框架对应物)手动编写这些图像来验证这一点。 因此,调整图像大小只会隐藏真正的问题,因为写一个较小的图像需要的时间较少。
问题可以通过限制编写器的数量和/或在出错的情况下重试来解决。 另请注意 - [UIActivityItemProvider item]是一个阻塞调用,但是没有同步方法可以直接写入库。这可以使用dispatch_semaphore_wait,NSCondition等处理。 或者,如果你正在使用ReactiveCocoa,只需调用waitUntilCompleted。
答案 1 :(得分:0)
我会说在保存到相机胶卷之前创建的[UIImage imageWithImage:image scaledToFitToSize:imageSize]
图像是GC,但我不知道在没有代码的情况下该方法发生了什么。那个方法不是普通的UIImage方法,也许是一个类别?
使用此代码替换添加到项目数组的for循环代码,然后取消注释调整大小行,看看是否有效。
NSMutableArray *itemArray = [[NSMutableArray alloc] init];
for( int i = 0; i < 9;i++)
{
UIImage *aiImage = [[[APLAsyncImageActivityItemProvider alloc] init] image];
[itemArray addObject:aiImage];
}