123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- #import "TTOpenInAppActivity.h"
- #import <MobileCoreServices/MobileCoreServices.h> // For UTI
- #import <ImageIO/ImageIO.h>
- @interface TTOpenInAppActivity () <UIActionSheetDelegate>
- @property (nonatomic, strong) NSArray *fileURLs;
- @property (atomic) CGRect rect;
- @property (nonatomic, strong) UIBarButtonItem *barButtonItem;
- @property (nonatomic, strong) UIView *superView;
- @property (nonatomic, strong) UIDocumentInteractionController *docController;
- - (NSString *)UTIForURL:(NSURL *)url;
- - (void)openDocumentInteractionControllerWithFileURL:(NSURL *)fileURL;
- - (void)openSelectFileActionSheet;
- @end
- @implementation TTOpenInAppActivity
- @synthesize rect = _rect;
- @synthesize superView = _superView;
- @synthesize superViewController = _superViewController;
- + (NSBundle *)bundle
- {
- NSBundle *bundle;
- NSURL *openInAppActivityBundleURL = [[NSBundle mainBundle] URLForResource:@"TTOpenInAppActivity" withExtension:@"bundle"];
- if (openInAppActivityBundleURL) {
-
- bundle = [NSBundle bundleWithURL:openInAppActivityBundleURL];
- } else {
- bundle = [NSBundle mainBundle];
- }
- return bundle;
- }
- - (id)initWithView:(UIView *)view andRect:(CGRect)rect
- {
- if(self =[super init]){
- self.superView = view;
- self.rect = rect;
- }
- return self;
- }
- - (id)initWithView:(UIView *)view andBarButtonItem:(UIBarButtonItem *)barButtonItem
- {
- if(self =[super init]){
- self.superView = view;
- self.barButtonItem = barButtonItem;
- }
- return self;
- }
- - (NSString *)activityType
- {
- return NSStringFromClass([self class]);
- }
- - (NSString *)activityTitle
- {
- return NSLocalizedStringFromTableInBundle(@"Open in ...", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil);
- }
- - (UIImage *)activityImage
- {
- if([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0){
- return [UIImage imageNamed:@"TTOpenInAppActivity8"];
- } else if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
- return [UIImage imageNamed:@"TTOpenInAppActivity7"];
- } else {
- return [UIImage imageNamed:@"TTOpenInAppActivity"];
- }
- }
- - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
- {
- NSUInteger count = 0;
-
- for (id activityItem in activityItems) {
- if ([activityItem isKindOfClass:[NSURL class]] && [(NSURL *)activityItem isFileURL]) {
- count++;
- }
- if ([activityItem isKindOfClass:[UIImage class]]) {
- count++;
- }
- }
-
- return (count >= 1);
- }
- - (void)prepareWithActivityItems:(NSArray *)activityItems
- {
- NSMutableArray *fileURLs = [NSMutableArray array];
-
- for (id activityItem in activityItems) {
- if ([activityItem isKindOfClass:[NSURL class]] && [(NSURL *)activityItem isFileURL]) {
- [fileURLs addObject:activityItem];
- }
- if ([activityItem isKindOfClass:[UIImage class]]) {
- NSURL *imageURL = [self localFileURLForImage:activityItem];
- [fileURLs addObject:imageURL];
- }
- }
-
- self.fileURLs = [fileURLs copy];
- }
- - (void)performActivity
- {
- if(!self.superViewController){
- [self activityDidFinish:YES];
- return;
- }
- void(^presentOpenIn)(void) = ^{
- if (self.fileURLs.count > 1) {
- [self openSelectFileActionSheet];
- }
- else {
-
- [self openDocumentInteractionControllerWithFileURL:self.fileURLs.lastObject];
- }
- };
-
- if ([self.superViewController respondsToSelector:@selector(dismissPopoverAnimated:)]) {
- [self.superViewController dismissPopoverAnimated:YES];
- [((UIPopoverController *)self.superViewController).delegate popoverControllerDidDismissPopover:self.superViewController];
-
- presentOpenIn();
- } else if([self.superViewController presentingViewController]) {
- [self.superViewController dismissViewControllerAnimated:YES completion:^(void){
- presentOpenIn();
- }];
- } else {
- presentOpenIn();
- }
- }
- #pragma mark - Helper
- - (NSString *)UTIForURL:(NSURL *)url
- {
- CFStringRef UTI = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)url.pathExtension, NULL);
- return (NSString *)CFBridgingRelease(UTI) ;
- }
- - (void)openDocumentInteractionControllerWithFileURL:(NSURL *)fileURL
- {
-
- self.docController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
- self.docController.delegate = self;
- self.docController.UTI = [self UTIForURL:fileURL];
- BOOL sucess;
-
- if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
- sucess = [self.docController presentOpenInMenuFromRect:CGRectZero inView:self.superView animated:YES];
- } else {
- if(self.barButtonItem){
- sucess = [self.docController presentOpenInMenuFromBarButtonItem:self.barButtonItem animated:YES];
- } else {
- sucess = [self.docController presentOpenInMenuFromRect:self.rect inView:self.superView animated:YES];
- }
- }
-
- if(!sucess){
-
- NSString *deviceType = [UIDevice currentDevice].localizedModel;
- NSString *message = [NSString stringWithFormat:NSLocalizedStringFromTableInBundle(@"Your %@ doesn't seem to have any other Apps installed that can open this document.", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil), deviceType];
-
- UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedStringFromTableInBundle(@"No suitable App installed", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil)
- message:message
- delegate:nil
- cancelButtonTitle:NSLocalizedStringFromTableInBundle(@"OK", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil)
- otherButtonTitles:nil];
- [alert show];
-
-
-
-
- [self activityDidFinish:NO];
- }
- }
- - (void)dismissDocumentInteractionControllerAnimated:(BOOL)animated {
-
- [self.docController dismissMenuAnimated:animated];
-
-
- [self activityDidFinish:NO];
- }
- - (void)openSelectFileActionSheet
- {
- UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedStringFromTableInBundle(@"Select a file", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil)
- delegate:self
- cancelButtonTitle:nil
- destructiveButtonTitle:nil
- otherButtonTitles:nil];
-
- for (NSURL *fileURL in self.fileURLs) {
- [actionSheet addButtonWithTitle:[fileURL lastPathComponent]];
- }
-
- actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedStringFromTableInBundle(@"Cancel", @"TTOpenInAppActivityLocalizable", [TTOpenInAppActivity bundle], nil)];
- if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
- [actionSheet showFromRect:CGRectZero inView:self.superView animated:YES];
- } else {
- if(self.barButtonItem){
- [actionSheet showFromBarButtonItem:self.barButtonItem animated:YES];
- } else {
- [actionSheet showFromRect:self.rect inView:self.superView animated:YES];
- }
- }
- }
- #pragma mark - UIDocumentInteractionControllerDelegate
- - (void) documentInteractionControllerWillPresentOpenInMenu:(UIDocumentInteractionController *)controller
- {
-
- if([self.delegate respondsToSelector:@selector(openInAppActivityWillPresentDocumentInteractionController:)]) {
- [self.delegate openInAppActivityWillPresentDocumentInteractionController:self];
- }
- }
- - (void) documentInteractionControllerDidDismissOpenInMenu: (UIDocumentInteractionController *) controller
- {
-
- if([self.delegate respondsToSelector:@selector(openInAppActivityDidDismissDocumentInteractionController:)]) {
- [self.delegate openInAppActivityDidDismissDocumentInteractionController:self];
- }
- }
- - (void) documentInteractionController:(UIDocumentInteractionController *)controller didEndSendingToApplication:(NSString *)application
- {
-
- if([self.delegate respondsToSelector:@selector(openInAppActivityDidEndSendingToApplication:)]) {
- [self.delegate openInAppActivityDidDismissDocumentInteractionController:self];
- }
- if ([self.delegate respondsToSelector:@selector(openInAppActivityDidSendToApplication:)]) {
- [self.delegate openInAppActivityDidSendToApplication:application];
- }
-
-
- [self activityDidFinish:YES];
- }
- #pragma mark - Action sheet delegate
- - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
- {
- if (buttonIndex != actionSheet.cancelButtonIndex) {
- [self openDocumentInteractionControllerWithFileURL:self.fileURLs[buttonIndex]];
- } else {
-
- [self activityDidFinish:NO];
- }
- }
- #pragma mark - Image conversion
- - (NSURL *)localFileURLForImage:(UIImage *)image
- {
-
- NSURL *tmpDirURL = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES];
- NSString *filename = [[NSUUID UUID] UUIDString];
- NSURL *fileURL;
-
- if (image.images) {
- fileURL = [[tmpDirURL URLByAppendingPathComponent:filename] URLByAppendingPathExtension:@"gif"];
- NSInteger frameCount = image.images.count;
- CGFloat frameDuration = image.duration / frameCount;
- NSDictionary *fileProperties = @{
- (__bridge id)kCGImagePropertyGIFDictionary: @{
- (__bridge id)kCGImagePropertyGIFLoopCount: @0,
- }
- };
- NSDictionary *frameProperties = @{
- (__bridge id)kCGImagePropertyGIFDictionary: @{
- (__bridge id)kCGImagePropertyGIFDelayTime: [NSNumber numberWithFloat:frameDuration],
- }
- };
- CGImageDestinationRef destination = CGImageDestinationCreateWithURL((__bridge CFURLRef)fileURL, kUTTypeGIF, frameCount, NULL);
- CGImageDestinationSetProperties(destination, (__bridge CFDictionaryRef)fileProperties);
- for (NSUInteger i = 0; i < frameCount; i++) {
- @autoreleasepool {
- UIImage *frameImage = [image.images objectAtIndex:i];
- CGImageDestinationAddImage(destination, frameImage.CGImage, (__bridge CFDictionaryRef)frameProperties);
- }
- }
- NSAssert(CGImageDestinationFinalize(destination),@"Failed to create animated image.");
- CFRelease(destination);
- } else {
- fileURL = [[tmpDirURL URLByAppendingPathComponent:filename] URLByAppendingPathExtension:@"jpg"];
- NSData *data = [NSData dataWithData:UIImageJPEGRepresentation(image, 0.8)];
- [[NSFileManager defaultManager] createFileAtPath:[fileURL path] contents:data attributes:nil];
- }
- return fileURL;
- }
- @end
|