VLCOpenInActivity.m 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. /*****************************************************************************
  2. * VLCOpenInActivity.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2014 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Marc Etcheverry <marc # taplightsoftware com>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCOpenInActivity.h"
  13. #import <MobileCoreServices/MobileCoreServices.h>
  14. @interface VLCOpenInActivity () <UIActionSheetDelegate, UIDocumentInteractionControllerDelegate>
  15. @end
  16. @implementation VLCOpenInActivity
  17. {
  18. NSMutableArray /* NSURL */ *_fileURLs;
  19. UIDocumentInteractionController *_documentInteractionController;
  20. }
  21. #pragma mark - UIActivity
  22. - (void)dealloc
  23. {
  24. _documentInteractionController.delegate = nil;
  25. }
  26. + (UIActivityCategory)activityCategory
  27. {
  28. return UIActivityCategoryAction;
  29. }
  30. - (NSString *)activityType
  31. {
  32. return NSStringFromClass([self class]);
  33. }
  34. - (NSString *)activityTitle
  35. {
  36. return NSLocalizedString(@"SHARING_ACTIVITY_OPEN_IN_TITLE", nil);
  37. }
  38. - (UIImage *)activityImage
  39. {
  40. return [UIImage imageNamed:@"OpenInActivityIcon"];
  41. }
  42. - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
  43. {
  44. for (id activityItem in activityItems) {
  45. if ([activityItem isKindOfClass:[NSURL class]] &&
  46. [(NSURL *)activityItem isFileURL]) {
  47. return YES;
  48. }
  49. }
  50. return NO;
  51. }
  52. - (void)prepareWithActivityItems:(NSArray *)activityItems
  53. {
  54. _fileURLs = [[NSMutableArray alloc] initWithCapacity:[activityItems count]];
  55. for (id activityItem in activityItems) {
  56. if ([activityItem isKindOfClass:[NSURL class]]
  57. && [(NSURL *)activityItem isFileURL]) {
  58. [_fileURLs addObject:activityItem];
  59. }
  60. }
  61. }
  62. - (void)performActivity
  63. {
  64. if (!self.presentingViewController || !self.presentingBarButtonItem) {
  65. [self activityDidFinish:NO];
  66. return;
  67. }
  68. NSUInteger count = [_fileURLs count];
  69. if (count > 1) {
  70. [self presentFileSelectionActionSheet];
  71. } else if (count == 1) {
  72. [self presentDocumentInteractionControllerWithFileURL:[_fileURLs firstObject]];
  73. } else {
  74. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_FILES", nil)
  75. message:nil
  76. delegate:nil
  77. cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
  78. otherButtonTitles:nil];
  79. [alertView show];
  80. [self activityDidFinish:NO];
  81. }
  82. }
  83. #pragma mark - UIDocumentInteractionController
  84. - (NSString *)UTTypeForFileURL:(NSURL *)url
  85. {
  86. CFStringRef UTTypeStringRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)url.pathExtension, NULL);
  87. return (NSString *)CFBridgingRelease(UTTypeStringRef);
  88. }
  89. - (void)presentDocumentInteractionControllerWithFileURL:(NSURL *)fileURL
  90. {
  91. NSParameterAssert(fileURL);
  92. if (!fileURL) {
  93. [self activityDidFinish:NO];
  94. return;
  95. }
  96. if (!self.presentingBarButtonItem) {
  97. [self activityDidFinish:NO];
  98. return;
  99. }
  100. _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
  101. _documentInteractionController.delegate = self;
  102. _documentInteractionController.UTI = [self UTTypeForFileURL:fileURL];
  103. __block BOOL controllerWasPresentedSuccessfully = NO;
  104. dispatch_block_t controllerPresentationBlock = ^{
  105. controllerWasPresentedSuccessfully = [_documentInteractionController presentOpenInMenuFromBarButtonItem:self.presentingBarButtonItem animated:YES];
  106. if (!controllerWasPresentedSuccessfully) {
  107. UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_APPLICATIONS", nil)
  108. message:nil
  109. delegate:nil
  110. cancelButtonTitle:NSLocalizedString(@"BUTTON_OK", nil)
  111. otherButtonTitles:nil];
  112. [alertView show];
  113. [self activityDidFinish:NO];
  114. }
  115. };
  116. if (![self.presentingViewController presentedViewController]) {
  117. controllerPresentationBlock();
  118. } else {
  119. [self.presentingViewController dismissViewControllerAnimated:YES completion:controllerPresentationBlock];
  120. }
  121. }
  122. #pragma mark - UIDocumentInteractionControllerDelegate
  123. - (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
  124. {
  125. [self activityDidFinish:YES];
  126. _documentInteractionController.delegate = nil;
  127. _documentInteractionController = nil;
  128. }
  129. #pragma mark - UIActionSheet
  130. - (void)presentFileSelectionActionSheet
  131. {
  132. [self.presentingViewController dismissViewControllerAnimated:YES completion:^{
  133. UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"SHARING_ACTION_SHEET_TITLE_CHOOSE_FILE", nil)
  134. delegate:self
  135. cancelButtonTitle:nil
  136. destructiveButtonTitle:nil
  137. otherButtonTitles:nil];
  138. for (NSURL *fileURL in _fileURLs) {
  139. [actionSheet addButtonWithTitle:[fileURL lastPathComponent]];
  140. }
  141. actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)];
  142. [actionSheet showFromBarButtonItem:self.presentingBarButtonItem animated:YES];
  143. }];
  144. }
  145. #pragma mark - UIActionSheetDelegate
  146. - (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
  147. {
  148. if (actionSheet.cancelButtonIndex != buttonIndex) {
  149. [self presentDocumentInteractionControllerWithFileURL:_fileURLs[buttonIndex]];
  150. } else {
  151. [self activityDidFinish:NO];
  152. }
  153. }
  154. @end