【问题标题】:How to exclude Notes and Reminders apps from the UIActivityViewController?如何从 UIActivityViewController 中排除笔记和提醒应用程序?
【发布时间】:2015-10-25 20:49:48
【问题描述】:

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

通过设置适当的excludedActivityTypes,我设法排除了许多系统提供的活动(例如“添加到阅读列表”)。

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

【问题讨论】:

    标签: ios cocoa-touch uiactivityviewcontroller uiactivity


    【解决方案1】:

    任何人在 2019 年都在这篇文章中磕磕绊绊。Reminders 扩展的关键随着 iOS 13 的变化而变化,现在是:

    (rawValue: "com.apple.reminders.sharingextension")
    

    【讨论】:

      【解决方案2】:

      有办法,但涉及到私有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 验证。

      【讨论】:

      • 非常感谢!我会试一试,如果它通过验证会通知你!
      • @AndriyGordiychuk 我想知道您是否已经知道它是否通过了 Apple 的验证。 :)
      • @Paulo 我的应用刚刚被批准使用这个。
      • 更新:Swift 3 打破了它。
      • @MatteoPacini 感谢您的出色工作。为我工作,我家 App Store 不会拒绝我的应用程序。 thanx 再次为我节省了几个小时。
      【解决方案3】:

      如果您不想继承 UIActivityViewController,您可以在创建 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];
      

      斯威夫特 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)
      

      【讨论】:

      • 唉,在 Swift 3、Xcode 8.1、iOS 9.3 中不起作用。提醒活动仍显示在共享表中。
      • 我可以通过这种方法在 iOS 10.3 上排除 Notes 应用程序,但正如 @Womble 所说,它不适用于 iOS 9.3。
      • 在 iOS 10.3 上非常适合我。
      • 适用于 ios 11。这应该是现在接受的答案。
      • 对于 iOS 13 使用 .init(rawValue: "com.apple.reminders.sharingextension")
      【解决方案4】:

      对于 Swift3+,不需要任何私有 API hack。只需使用 UIActivityViewController 上的公共“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)
      

      【讨论】:

      【解决方案5】:

      谢谢你! 在 xcode 8.1, swift 3 上,我可以用来获取:

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

      【讨论】:

        【解决方案6】:

        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"
        

        摆脱“云”。

        【讨论】:

        • 您是否设法使用 Apple 批准的此代码获取应用程序? :)
        • 还不知道。大约一周后提交。有点希望,因为 danielbmarques 似乎使用 objC 版本获得了批准(请参阅顶部答案中的 cmets)。
        • Apple Review 刚刚批准了我的应用程序
        • 非常棒且有用的答案 - 非常感谢。发送赏金。
        • 老实说不记得了,但我想你将 actType 打印到控制台,它会给你所有出现的应用程序的字符串。
        【解决方案7】:

        您不能排除这些,因为注释和提醒未在 Apple 文档中声明为 UIActivities。只是 iOS9 的一个问题,希望 Apple 会提供这个选项。到目前为止,声明的 UIActivity 是:

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

        【讨论】:

        • 1) 当然它们被声明为 UIActivities。问题是不包括相应的 UIActivityType 2) 毫无意义地建议 1 个月前提出的问题与今天提出的问题重复 :) 我知道在此期间不可能排除这些项目使用标准方法。但是,可能会有一些人知道的黑客行为。如果没有,Apple 将在某个时候解决此问题,并且问题将得到回答(喜欢它的人会收到通知):)
        【解决方案8】:

        我无法按照 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 中有没有办法做到这一点?
        【解决方案9】:

        我发现的唯一方法是创建自己的自定义活动,直接向它们传递参数(而不是通过活动表),然后通过活动表传递一些随机变量(不是字符串、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...希望很快会有更好的解决方案

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-21
          • 2020-09-27
          相关资源
          最近更新 更多