Как исключить приложения Notes и Reminders из UIActivityViewController?
Я создаю UIActivityViewController
и передать String
а также URL
к этому. Это, очевидно, настраивает UIActivityViewController
использовать некоторые элементы, которые я хочу исключить (моя цель - поделиться информацией о моем приложении).
Мне удалось исключить множество системных действий (например, "Добавить в список чтения"), установив соответствующие excludedActivityTypes
,
Однако я не могу исключить приложения "Напоминания" и "Заметки". Может кто-нибудь предложить способ сделать это? Эти приложения появляются в списке на 3-м и 4-м месте, поэтому Twitter и Facebook становятся невидимыми, если пользователь не выполняет прокрутку
8 ответов
Есть способ, но включает в себя частный API.
Иногда Apple делает исключения, особенно если вы исправляете ошибку.
Давайте углубимся в детали...
UIActivityViewController имеет закрытый метод, называемый "_availableActivitiesForItems:", который возвращает массив объектов UISocialActivity.
У UISocialActivity есть интересное свойство, называемое "activityType", которое возвращает тип активности в формате домена.
После некоторых тестов мне удалось обнаружить типы действий Reminder и Notes:
- 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.
Если вы не хотите подкласс 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];
Свифт 3:
let activityController = UIActivityViewController(activityItems: sharingItems, applicationActivities: nil)
activityController.excludedActivityTypes = [
UIActivityType.assignToContact,
UIActivityType.print,
UIActivityType.addToReadingList,
UIActivityType.saveToCameraRoll,
UIActivityType.openInIBooks,
UIActivityType(rawValue: "com.apple.reminders.RemindersEditorExtension"),
UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),
]
present(activityController, animated: true, completion: nil)
Версия Swift 2.2. Протестировано в iOS9.3. Работает.
ОБНОВЛЕНИЕ и получил одобрение обзора App Store.
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"
избавляется от "облачного".
Кто-нибудь наткнется на этот пост в 2019 году. Ключ для расширения напоминаний изменился с iOS 13 и теперь:
(rawValue: "com.apple.reminders.sharingextension")
Вы не можете исключить их, так как заметки и напоминания не объявлены как UIActivities
в документации Apple. Только проблема с iOS9 и, надеюсь, Apple предоставит эту опцию. Заявленные UIActivities до этого момента:
UIActivityTypePostToFacebook,
UIActivityTypePostToTwitter,
UIActivityTypePostToWeibo,
UIActivityTypeMessage,
UIActivityTypeMail,
UIActivityTypePrint,
UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList,
UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo,
UIActivityTypeAirDrop
Для Swift3+ не требуется никаких взломов Private API. Просто используйте публичный массив "selectedTypes" в 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)
Спасибо тебе за это! На xcode 8.1, swift 3 мне удалось получить:
UIActivityType (rawValue: "com.apple.reminders.RemindersEditorExtension"), UIActivityType (rawValue: "com.apple.mobilenotes.SharingExtension"),
Единственный способ, который я нашел, - это создать свои собственные пользовательские действия, передать им параметры напрямую (не через лист активности), а затем передать некоторую случайную переменную (не String, URL, Image) через лист активности.
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, если вы не можете использовать какую-либо функциональность... Надеюсь, скоро будет лучшее решение
Я не смог отправить _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];
}