web-dev-qa-db-fra.com

Comment exclure les applications Notes et Rappels de l'UIActivityViewController?

Je crée un UIActivityViewController et je lui passe String et URL. Ceci, évidemment, configure le UIActivityViewController pour utiliser certains éléments que je veux exclure (mon objectif est de partager les informations sur mon application).

J'ai réussi à exclure de nombreuses activités fournies par le système (comme "Ajouter à la liste de lecture") en définissant le excludedActivityTypes approprié.

Cependant, je ne peux pas exclure les applications Rappels et Notes. Quelqu'un peut-il suggérer une façon de procéder? Ces applications apparaissent 3ème et 4ème sur la liste et rendent donc Twitter et Facebook non visibles à moins que l'utilisateur défile.

52
Andriy Gordiychuk

Il existe un moyen, mais implique API privée.

Parfois Apple fait des exceptions, surtout si vous corrigez un bogue.

Plongeons-nous dans les détails ...


IActivityViewController a une méthode privée appelée "_availableActivitiesForItems:", qui renvoie un tableau d'objets ISocialActivity.

ISocialActivity possède une propriété intéressante, appelée "activityType", qui renvoie un type d'activité au format domaine.

Après quelques tests, j'ai réussi à découvrir les types d'activité Rappel et Notes:

  • com.Apple.reminders.RemindersEditorExtension
  • com.Apple.mobilenotes.SharingExtension

Malheureusement, le passage de ces deux types dans ".excludedActivityTypes" n'a fait aucune différence.

"_availableActivitiesForItems:" à la rescousse!

ANCIENNE VOIE:

pdate: J'ai trouvé une meilleure façon de le faire.

La première solution que j'ai publiée ne fonctionne pas dans certains cas, ne doit donc pas être considérée comme stable.

Entête:

#import <UIKit/UIKit.h>

@interface UISocialActivity : NSObject

- (id)activityType;

@end

@interface UIActivityViewController (Private)

- (id)_availableActivitiesForItems:(id)arg1;

@end

@interface ActivityViewController : UIActivityViewController

@end

La mise en oeuvre:

@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

NOUVELLE VOIE:

Entête:

@interface UIActivityViewController (Private)

- (BOOL)_shouldExcludeActivityType:(UIActivity*)activity;

@end

@interface ActivityViewController : UIActivityViewController

@end

La mise en oeuvre:

@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];
}

@fin

"Illégal", mais cela fonctionne.

Ce serait formidable de savoir s'il passe réellement la validation Apple.

18
Matteo Pacini

Si vous ne voulez pas sous-classer UIActivityViewController vous pouvez les inclure dans votre .excludedActivityTypes lors de la création de votre UIActivityViewController.

Objectif 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)
48
Daniel Storm

Version Swift 2.2. Testé dans iOS9.3. Travaux.

La mise à jour [~ # ~] [~ # ~] a été approuvée par l'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
    }

}

Aussi utile

 "com.Apple.mobileslideshow.StreamShareService"

se débarrasse de celui du "cloud".

enter image description here

34
guido

Vous ne pouvez pas les exclure car les notes et les rappels ne sont pas déclarés comme UIActivities dans la documentation Apple. Seul problème à partir d'iOS9 et, espérons-le Apple = fournira cette option Les activités UIA déclarées jusqu'à ce moment sont:

UIActivityTypePostToFacebook, 
UIActivityTypePostToTwitter, 
UIActivityTypePostToWeibo, 
UIActivityTypeMessage, 
UIActivityTypeMail, 
UIActivityTypePrint, 
UIActivityTypeCopyToPasteboard, 
UIActivityTypeAssignToContact,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList,
UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo,
UIActivityTypeAirDrop
6
scbojer

La seule façon que j'ai trouvée est de créer vos propres activités personnalisées, de leur transmettre directement des paramètres (pas via la feuille d'activité), puis de passer une variable aléatoire (pas une chaîne, une URL, une image) via la feuille d'activité.

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];

Mais là encore, pourquoi voudriez-vous utiliser ActivityViewController en premier lieu si vous ne pouvez utiliser aucune des fonctionnalités ... Espérons qu'il y aura bientôt une meilleure solution

2
eirik

Pour Swift3 +, aucun piratage d'API privé n'est nécessaire. Utilisez simplement le tableau public "exclusTypes" sur le UIActivityViewController. Comme il n'y a toujours pas d'UIActivityType pour ces derniers (car ce sont des extensions construites par Apple), vous devez vous y référer via String. Vous pouvez également utiliser ce format pour toutes les extensions de partage tierces.

par exemple.

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
mm282

Merci pour ça! Sur xcode 8.1, Swift 3, j'ai pu utiliser pour obtenir:

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

2
test ing

Je n'ai pas pu envoyer _shouldExcludeActivityType à Super comme recommandé par Matteo Pacini, mais voici comment je peux contourner ce problème:

@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
Johannes Eichler