How to exclude Notes and Reminder applications from UIActivityViewController?

I create a UIActivityViewController and pass it String and URL . This obviously configures the UIActivityViewController to use some elements that I want to exclude (my goal is to share information about my application).

I managed to exclude many operations with the system (for example, "Add to the reading list") by setting the corresponding excludedActivityTypes .

However, I can not exclude the application reminders and notes. Can anyone suggest a way to do this? These applications appear on the 3rd and 4th in the list and therefore make Twitter and Facebook invisible if the user does not scroll the page.

+52
ios cocoa-touch uiactivityviewcontroller uiactivity
Aug 03 '15 at 16:38
source share
8 answers

There is a way, but it includes a private API .

Sometimes Apple makes exceptions, especially if you are fixing a bug.

Let's dive into the details ...




UIActivityViewController has a private method called _availableActivitiesForItems: which returns an array of UISocialActivity objects.

UISocialActivity has an interesting property called "activityType" that returns the type of action in the domain format.

After some tests, I managed to discover the types of actions "Reminder and notes":

  • com.apple.reminders.RemindersEditorExtension
  • com.apple.mobilenotes.SharingExtension

Unfortunately , passing these two types to ".excludedActivityTypes" does not matter.

"_availableActivitiesForItems:" to the rescue!

OLD WAY :

Update : I found a better way to do this.

The first solution I posted does not work in some cases, so it should not be considered stable.

Title:

 #import <UIKit/UIKit.h> @interface UISocialActivity : NSObject - (id)activityType; @end @interface UIActivityViewController (Private) - (id)_availableActivitiesForItems:(id)arg1; @end @interface ActivityViewController : UIActivityViewController @end 

Implementation:

 @implementation ActivityViewController - (id)_availableActivitiesForItems:(id)arg1 { id activities = [super _availableActivitiesForItems:arg1]; NSMutableArray *filteredActivities = [NSMutableArray array]; [activities enumerateObjectsUsingBlock:^(UISocialActivity* _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { if (![[obj activityType] isEqualToString:@"com.apple.reminders.RemindersEditorExtension"] && ![[obj activityType] isEqualToString:@"com.apple.mobilenotes.SharingExtension"]) { [filteredActivities addObject:obj]; } }]; return [NSArray arrayWithArray:filteredActivities]; } @end 

NEW WAY :

Title:

 @interface UIActivityViewController (Private) - (BOOL)_shouldExcludeActivityType:(UIActivity*)activity; @end @interface ActivityViewController : UIActivityViewController @end 

Implementation:

 @implementation ActivityViewController - (BOOL)_shouldExcludeActivityType:(UIActivity *)activity { if ([[activity activityType] isEqualToString:@"com.apple.reminders.RemindersEditorExtension"] || [[activity activityType] isEqualToString:@"com.apple.mobilenotes.SharingExtension"]) { return YES; } return [super _shouldExcludeActivityType:activity]; } 

@end

" Illegal ", but it works.

It would be great to know if it really passes the Apple test.

+18
Oct 22 '15 at 17:05
source share

If you do not want the UIActivityViewController subclass of the UIActivityViewController you can include them in your .excludedActivityTypes when creating the UIActivityViewController .

Goal C:

 UIActivityViewController *activityController = [[UIActivityViewController alloc]initWithActivityItems:sharingItems applicationActivities:nil]; activityController.excludedActivityTypes = @[ UIActivityTypeAssignToContact, UIActivityTypePrint, UIActivityTypeAddToReadingList, UIActivityTypeSaveToCameraRoll, UIActivityTypeOpenInIBooks, @"com.apple.mobilenotes.SharingExtension", @"com.apple.reminders.RemindersEditorExtension" ]; [self presentViewController:activityController animated:YES completion:nil]; 

Swift 4.2:

 let activityController = UIActivityViewController(activityItems: sharingItems, applicationActivities: nil) activityController.excludedActivityTypes = [ UIActivity.ActivityType.assignToContact, UIActivity.ActivityType.print, UIActivity.ActivityType.addToReadingList, UIActivity.ActivityType.saveToCameraRoll, UIActivity.ActivityType.openInIBooks, UIActivity.ActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivity.ActivityType(rawValue: "com.apple.mobilenotes.SharingExtension")] present(activityController, animated: true, completion: nil) 
+47
Sep 26 '16 at 19:31
source share

Swift version 2.2. Tested in iOS9.3. Works.

UPDATE and received approval from the App Store Review.

 import UIKit class ActivityViewController: UIActivityViewController { func _shouldExcludeActivityType(activity: UIActivity) -> Bool { let activityTypesToExclude = [ "com.apple.reminders.RemindersEditorExtension", "com.apple.mobilenotes.SharingExtension", UIActivityTypeOpenInIBooks, UIActivityTypePrint, UIActivityTypeAssignToContact, "com.google.Drive.ShareExtension" ] if let actType = activity.activityType() { if activityTypesToExclude.contains(actType) { return true } else if super.excludedActivityTypes != nil { return super.excludedActivityTypes!.contains(actType) } } return false } } 

Also useful

  "com.apple.mobileslideshow.StreamShareService" 

gets rid of the cloud.

enter image description here

+33
May 13 '16 at 19:13
source share

You cannot exclude them, since Notes and reminders are not declared as UIActivities in the Apple documentation. Only a problem with iOS9 and hopefully Apple will provide this option. Announced UIActivities up to this point:

 UIActivityTypePostToFacebook, UIActivityTypePostToTwitter, UIActivityTypePostToWeibo, UIActivityTypeMessage, UIActivityTypeMail, UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList, UIActivityTypePostToFlickr, UIActivityTypePostToVimeo, UIActivityTypePostToTencentWeibo, UIActivityTypeAirDrop 
+6
Sep 22 '15 at 14:24
source share

The only way I found is to create your own custom actions, pass parameters to them directly (and not through the activity sheet), and then pass some random variable (not lines, URLs, images) through the activity sheet.

 MyCustomPinterestShareActivity* pinterest = [[MyCustomPinterestShareActivity alloc] init]; MyCustomFacebookGroupsActivity* facebook = [[MyCustomFacebookGroupsActivity alloc] init]; MyCustomInstagramActivity* instagram = [[MyCustomInstagramActivity alloc] init]; NSArray *activities = @[facebook,instagram,pinterest]; NSArray *activityItems = @[someVarThatCanBeWhateverTypeJustNotStringURLOrImg]; UIActivityViewController *activityView = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:activities]; 

But then again, why do you want to use the ActivityViewController in the first place, if you cannot use any functionality ... I hope there will soon be a better solution.

+2
Oct 07 '15 at 18:01
source share

Thanks for this! In xcode 8.1, swift 3, I was able to use to get:

UIActivityType (rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivityType (rawValue: "com.apple.mobilenotes.SharingExtension"),

+2
Nov 26 '16 at 20:45
source share

There is no need for Private API hackers for Swift3 +. Just use the public array "excludedTypes" in the UIActivityViewController. Since there is no UIActivityType for them yet (since they are Apple's built-in extensions), you need to access it via String. You can also use this format for third-party sharing extensions.

eg.

 let avc = UIActivityViewController(activityItems: ["my item"], applicationActivities: nil) avc.excludedActivityTypes = [ .copyToPasteboard, UIActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension") ] avc.completionWithItemsHandler = { (activity, success, items, error) in print("AVC finished \(success) \(activity as Optional) \(items as Optional) \(error as Optional)") } present(avc, animated: true, completion: nil) 
+2
Sep 05 '17 at 8:22
source share

I could not send _shouldExcludeActivityType to Super, as recommended by Matteo Pacini, but here is how I could do it:

 @interface CustomActivityViewController() - (BOOL)_shouldExcludeActivityType:(UIActivity *)activity; @end @implementation CustomActivityViewController (...) - (BOOL)_shouldExcludeActivityType:(UIActivity *)activity{ if([[activity activityType] isEqualToString:@"com.apple.reminders.RemindersEditorExtension"] || [[activity activityType] isEqualToString:@"com.apple.mobilenotes.SharingExtension"]){ return YES; } return [[super excludedActivityTypes]containsObject:activity.activityType]; } 
+1
Nov 23 '15 at 13:23
source share



All Articles