Подтвердить что ты не робот

Как исключить приложения Notes и напоминаний из UIActivityViewController?

Я создаю UIActivityViewController и передаю ему String и URL. Это, очевидно, настраивает UIActivityViewController для использования некоторых элементов, которые я хочу исключить (моя цель - поделиться информацией о моем приложении).

Мне удалось исключить множество операций с системой (например, "Добавить в список чтения" ), установив соответствующий excludedActivityTypes.

Однако я не могу исключить приложения напоминаний и заметок. Может кто-нибудь предложить способ сделать это? Эти приложения появляются 3-го и 4-го в списке и поэтому делают Twitter и Facebook невидимыми, если пользователь не прокручивает страницы.

4b9b3361

Ответ 1

Есть способ, но включает в себя частный API.

Иногда Apple делает исключения, особенно если вы исправляете ошибку.

Давайте погрузимся в детали...


UIActivityViewController имеет закрытый метод, называемый _availableActivitiesForItems:, который возвращает массив объектов UISocialActivity.

UISocialActivity имеет интересное свойство, называемое "activityType", которое возвращает тип действия в формате домена.

После некоторых тестов мне удалось обнаружить типы действий "Напоминание и заметки":

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

К сожалению, передача этих двух типов в ".excludedActivityTypes" не имеет никакого значения.

"_availableActivitiesForItems:" на помощь!

СТАРЫЙ ПУТЬ:

Обновление: я нашел лучший способ сделать это.

Первое решение, которое я опубликовал, в некоторых случаях не работает, поэтому не должно считаться стабильным.

Заголовок:

#import <UIKit/UIKit.h>

@interface UISocialActivity : NSObject

- (id)activityType;

@end

@interface UIActivityViewController (Private)

- (id)_availableActivitiesForItems:(id)arg1;

@end

@interface ActivityViewController : UIActivityViewController

@end

Реализация:

@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

НОВЫЙ ПУТЬ:

Заголовок:

@interface UIActivityViewController (Private)

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

@end

@interface ActivityViewController : UIActivityViewController

@end

Реализация:

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

@конец

" Незаконно ", но это работает.

Было бы здорово узнать, действительно ли он проходит проверку Apple.

Ответ 2

Если вы не хотите UIActivityViewController подкласс UIActivityViewController вы можете включить их в свои .excludedActivityTypes при создании UIActivityViewController.

Цель 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)

Ответ 3

версия Swift 2.2. Протестировано в iOS9.3. Работает.

UPDATE и получил одобрение 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
    }

}

Также полезно

 "com.apple.mobileslideshow.StreamShareService"

избавляется от "облачного".

введите описание изображения здесь

Ответ 4

Вы не можете исключить их, поскольку Notes и напоминания не объявляются как UIActivities в документации Apple. Только проблема с iOS9 и, надеюсь, Apple предоставит этот вариант. Объявленные UIActivities до этого момента:

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

Ответ 5

Единственным способом, который я нашел, является создание ваших собственных пользовательских действий, передача параметров им напрямую (а не через лист активности), а затем передача некоторой случайной переменной (не строки, URL-адреса, изображения) через лист активности.

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

Но опять же, почему вы хотите использовать ActivityViewController в первую очередь, если вы не можете использовать какую-либо функциональность... Надеюсь, скоро будет лучшее решение.

Ответ 6

Спасибо за это! В xcode 8.1, swift 3, я смог использовать, чтобы получить:

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

Ответ 7

Для Swift3 + нет необходимости в хакерах Private API. Просто используйте публичный массив "excludedTypes" в UIActivityViewController. Поскольку для них еще нет UIActivityType (поскольку они являются встроенными расширениями Apple), вам нужно обратиться к нему через String. Вы также можете использовать этот формат для сторонних разделяющих расширений.

например.

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)

Ответ 8

Я не мог отправить _shouldExcludeActivityType в Super, как рекомендовал Маттео Пачини, но вот как я мог это сделать:

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

 }