VLCOpenInActivity.m 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. #import "VLC-Swift.h"
  16. @interface VLCOpenInActivity () <UIDocumentInteractionControllerDelegate>
  17. @end
  18. @implementation VLCOpenInActivity
  19. {
  20. NSMutableArray /* NSURL */ *_fileURLs;
  21. UIDocumentInteractionController *_documentInteractionController;
  22. }
  23. #pragma mark - UIActivity
  24. + (UIActivityCategory)activityCategory
  25. {
  26. return UIActivityCategoryAction;
  27. }
  28. - (NSString *)activityType
  29. {
  30. return NSStringFromClass([self class]);
  31. }
  32. - (NSString *)activityTitle
  33. {
  34. return NSLocalizedString(@"SHARING_ACTIVITY_OPEN_IN_TITLE", nil);
  35. }
  36. - (UIImage *)activityImage
  37. {
  38. return [UIImage imageNamed:@"OpenInActivityIcon"];
  39. }
  40. - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems
  41. {
  42. for (id activityItem in activityItems) {
  43. if ([activityItem isKindOfClass:[NSURL class]] &&
  44. [(NSURL *)activityItem isFileURL]) {
  45. return YES;
  46. }
  47. }
  48. return NO;
  49. }
  50. - (void)prepareWithActivityItems:(NSArray *)activityItems
  51. {
  52. _fileURLs = [[NSMutableArray alloc] initWithCapacity:[activityItems count]];
  53. for (id activityItem in activityItems) {
  54. if ([activityItem isKindOfClass:[NSURL class]]
  55. && [(NSURL *)activityItem isFileURL]) {
  56. [_fileURLs addObject:activityItem];
  57. }
  58. }
  59. }
  60. - (void)performActivity
  61. {
  62. if (!self.presentingViewController || !self.presentingBarButtonItem) {
  63. [self activityDidFinish:NO];
  64. return;
  65. }
  66. NSUInteger count = [_fileURLs count];
  67. if (count > 1) {
  68. [self presentFileSelectionActionController];
  69. } else if (count == 1) {
  70. [self presentDocumentInteractionControllerWithFileURL:[_fileURLs firstObject]];
  71. } else {
  72. [VLCAlertViewController alertViewManagerWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_FILES", nil)
  73. errorMessage:nil
  74. viewController:self.activityViewController];
  75. [self activityDidFinish:NO];
  76. }
  77. }
  78. #pragma mark - UIDocumentInteractionController
  79. - (NSString *)UTTypeForFileURL:(NSURL *)url
  80. {
  81. CFStringRef UTTypeStringRef = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)url.pathExtension, NULL);
  82. return (NSString *)CFBridgingRelease(UTTypeStringRef);
  83. }
  84. - (void)presentDocumentInteractionControllerWithFileURL:(NSURL *)fileURL
  85. {
  86. NSParameterAssert(fileURL);
  87. if (!fileURL) {
  88. [self activityDidFinish:NO];
  89. return;
  90. }
  91. if (!self.presentingBarButtonItem) {
  92. [self activityDidFinish:NO];
  93. return;
  94. }
  95. _documentInteractionController = [UIDocumentInteractionController interactionControllerWithURL:fileURL];
  96. _documentInteractionController.delegate = self;
  97. _documentInteractionController.UTI = [self UTTypeForFileURL:fileURL];
  98. __block BOOL controllerWasPresentedSuccessfully = NO;
  99. dispatch_block_t controllerPresentationBlock = ^{
  100. controllerWasPresentedSuccessfully = [self->_documentInteractionController presentOpenInMenuFromBarButtonItem:self.presentingBarButtonItem animated:YES];
  101. if (!controllerWasPresentedSuccessfully) {
  102. [VLCAlertViewController alertViewManagerWithTitle:NSLocalizedString(@"SHARING_ERROR_NO_APPLICATIONS", nil)
  103. errorMessage:nil
  104. viewController:self.activityViewController];
  105. [self activityDidFinish:NO];
  106. }
  107. };
  108. if (![self.presentingViewController presentedViewController]) {
  109. controllerPresentationBlock();
  110. } else {
  111. [self.presentingViewController dismissViewControllerAnimated:YES completion:controllerPresentationBlock];
  112. }
  113. }
  114. #pragma mark - UIDocumentInteractionControllerDelegate
  115. - (void)documentInteractionControllerDidDismissOpenInMenu:(UIDocumentInteractionController *)controller
  116. {
  117. [self activityDidFinish:YES];
  118. _documentInteractionController = nil;
  119. }
  120. #pragma mark - UIAlertController
  121. - (void)presentFileSelectionActionController
  122. {
  123. UIAlertController *actionController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"SHARING_ACTION_SHEET_TITLE_CHOOSE_FILE", nil)
  124. message:nil
  125. preferredStyle:UIAlertControllerStyleActionSheet];
  126. for (NSURL *fileURL in _fileURLs) {
  127. UIAlertAction *action = [UIAlertAction actionWithTitle:[fileURL lastPathComponent]
  128. style:UIAlertActionStyleDefault
  129. handler:^(UIAlertAction * _Nonnull action) {
  130. [self presentDocumentInteractionControllerWithFileURL:fileURL];
  131. }];
  132. [actionController addAction:action];
  133. }
  134. UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"BUTTON_CANCEL", nil)
  135. style:UIAlertActionStyleCancel
  136. handler:^(UIAlertAction * _Nonnull action) {
  137. [self activityDidFinish:NO];
  138. }];
  139. [actionController addAction:cancelAction];
  140. [self.presentingViewController presentViewController:actionController animated:YES completion:nil];
  141. }
  142. @end