VLCOpenInActivity.m 6.4 KB

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