Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to exclude Notes and Reminders apps from the UIActivityViewController?

I am creating a UIActivityViewController and pass String and URL to it. This, obviously, configures the UIActivityViewController to use some items which I want to exclude (my objective is to share the info about my app).

I have managed to exclude lots of system provided activities (like 'Add to Reading list') by setting the appropriate excludedActivityTypes.

However, I am unable to exclude Reminders and Notes apps. Can someone suggest a way of doing it? These apps appear 3rd and 4th on the list and therefore make Twitter and Facebook not visible unless user scrolls.

like image 811
Andriy Gordiychuk Avatar asked Aug 03 '15 16:08

Andriy Gordiychuk


4 Answers

If you don't want to subclass UIActivityViewController you can include them in your .excludedActivityTypes when creating your UIActivityViewController.

Objective 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)
like image 64
Daniel Storm Avatar answered Nov 10 '22 02:11

Daniel Storm


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

UPDATE and got approved by 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" one.

enter image description here

like image 35
guido Avatar answered Nov 10 '22 01:11

guido


There is a way, but involves private API.

Sometimes Apple makes exceptions, especially if you fix a bug.

Let's dive into details...


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

UISocialActivity has got an interesting property, called "activityType", which returns a domain-formatted activity type.

After some tests, I managed to discover the Reminder and Notes activity types:

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

Unfortunately, passing those two types into ".excludedActivityTypes" didn't make any difference.

"_availableActivitiesForItems:" to the rescue!

OLD WAY:

Update: I've found a better way to do it.

The first solution I've posted doesn't work in some cases, thus shouldn't be considered stable.

Header:

#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:

Header:

@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 actually passes Apple validation.

like image 21
Matteo Pacini Avatar answered Nov 10 '22 00:11

Matteo Pacini


Anybody stumbling in this post in 2019. The key for the Reminders extension changed with iOS 13 and is now:

(rawValue: "com.apple.reminders.sharingextension")
like image 8
TimLR Avatar answered Nov 10 '22 00:11

TimLR