Как исключить приложения Notes и напоминаний из UIActivityViewController?
Я создаю UIActivityViewController
и передаю ему String
и URL
. Это, очевидно, настраивает UIActivityViewController
для использования некоторых элементов, которые я хочу исключить (моя цель - поделиться информацией о моем приложении).
Мне удалось исключить множество операций с системой (например, "Добавить в список чтения" ), установив соответствующий excludedActivityTypes
.
Однако я не могу исключить приложения напоминаний и заметок. Может кто-нибудь предложить способ сделать это? Эти приложения появляются 3-го и 4-го в списке и поэтому делают Twitter и Facebook невидимыми, если пользователь не прокручивает страницы.
Ответы
Ответ 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];
}