如何从UIActivityViewController中排除Notes和提醒应用程序?

我正在创build一个UIActivityViewController并将StringURL传递给它。 这显然,configurationUIActivityViewController使用一些项目,我想排除(我的目标是共享有关我的应用程序的信息)。

我设法排除了大量系统提供的活动(如“添加到阅读列表”),方法是设置适当的excludedActivityTypes

但是,我无法排除提醒和Notes应用程序。 有人可以提出一种方法吗? 这些应用程序在列表中显示第3和第4,因此除非用户滚动,否则Twitter和Facebook将不可见。

有一种方法,但涉及私有API

有时苹果会制造exception,特别是如果你修复了一个错误。

让我们深入细节…


UIActivityViewController有一个名为“_availableActivitiesForItems:”的私有方法,它返回一个UISocialActivity对象的数组。

UISocialActivity有一个有趣的属性,称为“activityType”,它返回一个域格式的活动types。

经过一些testing后,我发现了Reminder和Notes活动types:

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

不幸的是 ,将这两种types传递给“.excludedActivityTypes”没有任何区别。

“_availableActivitiesForItems:”来拯救!

旧的方式

更新 :我发现了一个更好的方法来做到这一点。

我发布的第一个解决scheme在某些情况下不起作用,因此不应该被认为是稳定的。

标题:

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

@结束

“非法”,但它的作品。

知道它是否真的通过了苹果validation真是太好了。

Swift 2.2版本。 在iOS9.3中testing 作品。

更新并获得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" 

摆脱“云”之一。

在这里输入图像描述

如果你不想子类UIActivityViewController你可以在创build你的UIActivityViewController时将它们包含在.excludedActivityTypes

目标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 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) 

您不能排除这些因为Notes和Reminders没有在Apple文档中声明为UIActivities 。 只有iOS9的问题,并希望苹果将提供这个选项。 直到目前为止宣布的UIActivities是:

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

我发现的唯一方法是创build自己的自定义活动,直接传递参数(不通过活动工作表),然后通过活动工作表传递一些随机variables(不是string,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]; 

但是再一次,如果你不能使用任何function,你为什么要首先使用ActivityViewController?希望稍后会有更好的解决scheme

这次真是万分感谢! 在xcode 8.1,swift 3上,我可以使用得到:

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

对于Swift3 +,不需要任何私人API的黑客攻击。 只需使用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) 

按照Matteo Pacini的build议,我无法将_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]; }