如何从 UIActivityViewController 中排除笔记和提醒应用程序?
How to exclude Notes and Reminders apps from the UIActivityViewController?
我正在创建一个 UIActivityViewController
并将 String
和 URL
传递给它。显然,这会将 UIActivityViewController
配置为使用一些我想排除的项目(我的 objective 是共享有关我的应用程序的信息)。
我通过设置适当的 excludedActivityTypes
.
设法排除了许多系统提供的活动(例如 'Add to Reading list')
但是,我无法排除提醒和便签应用程序。有人可以建议一种方法吗?这些应用程序在列表中排名第 3 和第 4,因此除非用户滚动,否则 Twitter 和 Facebook 不可见。
您不能排除这些,因为 Apple 文档中未将注释和提醒声明为 UIActivities
。截至 iOS9 只有一个问题,希望 Apple 会提供此选项。到目前为止声明的 UIActivities 是:
UIActivityTypePostToFacebook,
UIActivityTypePostToTwitter,
UIActivityTypePostToWeibo,
UIActivityTypeMessage,
UIActivityTypeMail,
UIActivityTypePrint,
UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList,
UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo,
UIActivityTypeAirDrop
我发现的唯一方法是创建您自己的自定义活动,直接将参数传递给它们(而不是通过 activity sheet),然后传递一些随机变量(不是字符串,URL,Image)通过activitysheet。
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...希望很快会有更好的解决方案
有办法,但是涉及私有API.
有时 Apple 会破例,尤其是当您修复错误时。
让我们深入了解细节...
UIActivityViewController 有一个名为“_availableActivitiesForItems:”的私有方法,returns UISocialActivity [=96] 的数组=].
UISocialActivity 有一个有趣的 属性,叫做 "activityType",其中 returns 一个 domain-formatted activity类型。
经过一些测试,我设法发现了提醒和备注 activity 类型:
- com.apple.reminders.RemindersEditorExtension
- com.apple.mobilenotes.SharingExtension
不幸的是,将这两种类型传递给“.excludedActivityTypes”没有任何区别。
“_availableActivitiesForItems:”拯救!
旧方法:
更新:我找到了更好的方法。
我发布的第一个解决方案在某些情况下不起作用,因此不应被认为是稳定的。
Header:
#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
新方式:
Header:
@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];
}
@end
"非法",但有效。
很高兴知道它是否真的通过了 Apple 验证。
我无法按照 Matteo Pacini 的建议将 _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];
}
Swift 2.2 版本。在 iOS9.3 中测试。有效。
更新 并通过 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"
去掉 "cloud" 一个。
如果您不想子类化 UIActivityViewController
,您可以在创建 UIActivityViewController
.
时将它们包含在您的 .excludedActivityTypes
中
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)
谢谢你!
在 xcode 8.1、swift 3 上,我能够使用得到:
UIActivityType(原始值: "com.apple.reminders.RemindersEditorExtension"),
UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),
对于 Swift3+,不需要任何 Private API hack。只需在 UIActivityViewController 上使用 public "excludedTypes" 数组。由于这些仍然没有 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)
任何人在 2019 年遇到这个 post。提醒扩展的密钥随着 iOS 13 发生了变化,现在是:
(rawValue: "com.apple.reminders.sharingextension")
我正在创建一个 UIActivityViewController
并将 String
和 URL
传递给它。显然,这会将 UIActivityViewController
配置为使用一些我想排除的项目(我的 objective 是共享有关我的应用程序的信息)。
我通过设置适当的 excludedActivityTypes
.
但是,我无法排除提醒和便签应用程序。有人可以建议一种方法吗?这些应用程序在列表中排名第 3 和第 4,因此除非用户滚动,否则 Twitter 和 Facebook 不可见。
您不能排除这些,因为 Apple 文档中未将注释和提醒声明为 UIActivities
。截至 iOS9 只有一个问题,希望 Apple 会提供此选项。到目前为止声明的 UIActivities 是:
UIActivityTypePostToFacebook,
UIActivityTypePostToTwitter,
UIActivityTypePostToWeibo,
UIActivityTypeMessage,
UIActivityTypeMail,
UIActivityTypePrint,
UIActivityTypeCopyToPasteboard,
UIActivityTypeAssignToContact,
UIActivityTypeSaveToCameraRoll,
UIActivityTypeAddToReadingList,
UIActivityTypePostToFlickr,
UIActivityTypePostToVimeo,
UIActivityTypePostToTencentWeibo,
UIActivityTypeAirDrop
我发现的唯一方法是创建您自己的自定义活动,直接将参数传递给它们(而不是通过 activity sheet),然后传递一些随机变量(不是字符串,URL,Image)通过activitysheet。
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...希望很快会有更好的解决方案
有办法,但是涉及私有API.
有时 Apple 会破例,尤其是当您修复错误时。
让我们深入了解细节...
UIActivityViewController 有一个名为“_availableActivitiesForItems:”的私有方法,returns UISocialActivity [=96] 的数组=].
UISocialActivity 有一个有趣的 属性,叫做 "activityType",其中 returns 一个 domain-formatted activity类型。
经过一些测试,我设法发现了提醒和备注 activity 类型:
- com.apple.reminders.RemindersEditorExtension
- com.apple.mobilenotes.SharingExtension
不幸的是,将这两种类型传递给“.excludedActivityTypes”没有任何区别。
“_availableActivitiesForItems:”拯救!
旧方法:
更新:我找到了更好的方法。
我发布的第一个解决方案在某些情况下不起作用,因此不应被认为是稳定的。
Header:
#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
新方式:
Header:
@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];
}
@end
"非法",但有效。
很高兴知道它是否真的通过了 Apple 验证。
我无法按照 Matteo Pacini 的建议将 _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];
}
Swift 2.2 版本。在 iOS9.3 中测试。有效。
更新 并通过 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"
去掉 "cloud" 一个。
如果您不想子类化 UIActivityViewController
,您可以在创建 UIActivityViewController
.
.excludedActivityTypes
中
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)
谢谢你! 在 xcode 8.1、swift 3 上,我能够使用得到:
UIActivityType(原始值: "com.apple.reminders.RemindersEditorExtension"), UIActivityType(rawValue: "com.apple.mobilenotes.SharingExtension"),
对于 Swift3+,不需要任何 Private API hack。只需在 UIActivityViewController 上使用 public "excludedTypes" 数组。由于这些仍然没有 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)
任何人在 2019 年遇到这个 post。提醒扩展的密钥随着 iOS 13 发生了变化,现在是:
(rawValue: "com.apple.reminders.sharingextension")