ios 如何从 UIActivityViewController 中排除 Notes 和 Reminders 应用程序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31792506/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 07:08:19  来源:igfitidea点击:

How to exclude Notes and Reminders apps from the UIActivityViewController?

ioscocoa-touchuiactivityviewcontrolleruiactivity

提问by Andriy Gordiychuk

I am creating a UIActivityViewControllerand pass Stringand URLto it. This, obviously, configures the UIActivityViewControllerto use some items which I want to exclude (my objective is to share the info about my app).

我创建UIActivityViewController并通过StringURL它。显然,这将配置UIActivityViewController为使用我想排除的一些项目(我的目标是共享有关我的应用程序的信息)。

I have managed to exclude lots of system provided activities (like 'Add to Reading list') by setting the appropriate excludedActivityTypes.

通过设置适当的excludedActivityTypes.

However, I am unable to exclude Reminders and Notes apps. Can someone suggest a way of doing it? These apps appear 3rd and 4th on the list and therefore make Twitter and Facebook not visible unless user scrolls.

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

采纳答案by Matteo Pacini

There is a way, but involves private API.

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

Sometimes Apple makes exceptions, especially if you fix a bug.

有时 Apple 会例外,尤其是在您修复错误的情况下。

Let's dive into details...

让我们深入了解细节......



UIActivityViewControllerhas got a private method called "_availableActivitiesForItems:", which returns an array of UISocialActivityobjects.

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

UISocialActivityhas got an interesting property, called "activityType", which returns a domain-formatted activity type.

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

After some tests, I managed to discover the Reminder and Notes activity types:

经过一些测试,我设法发现了 Reminder 和 Notes 活动类型:

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

Unfortunately, passing those two types into ".excludedActivityTypes" didn't make any difference.

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

"_availableActivitiesForItems:" to the rescue!

“_availableActivitiesForItems:”来救援!

OLD WAY:

旧方式

Update: I've found a better way to do it.

更新:我找到了更好的方法。

The first solution I've posted doesn't work in some cases, thus shouldn't be considered stable.

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

Header:

标题:

#import <UIKit/UIKit.h>

@interface UISocialActivity : NSObject

- (id)activityType;

@end

@interface UIActivityViewController (Private)

- (id)_availableActivitiesForItems:(id)arg1;

@end

@interface ActivityViewController : UIActivityViewController

@end

Implementation:

@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
#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

NEW WAY:

新方式

Header:

标题:

@interface UIActivityViewController (Private)

- (BOOL)_shouldExcludeActivityType:(UIActivity*)activity;

@end

@interface ActivityViewController : UIActivityViewController

@end

Implementation:

执行:

@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

@结尾

"Illegal", but it works.

非法”,但它有效。

It would be great to know if it actually passes Apple validation.

很高兴知道它是否真的通过了 Apple 验证。

回答by Daniel Storm

If you don't want to subclass UIActivityViewControlleryou can include them in your .excludedActivityTypeswhen creating your UIActivityViewController.

如果您不想子类化UIActivityViewController,则可以.excludedActivityTypes在创建UIActivityViewController.

Objective C:

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

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

回答by guido

Swift 2.2 version. Tested in iOS9.3. Works.

斯威夫特 2.2 版本。在iOS9.3中测试。作品。

UPDATEand got approved by App Store Review.

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

}

Also useful

也有用

 "com.apple.mobileslideshow.StreamShareService"

gets rid of the "cloud" one.

摆脱“云”一。

enter image description here

在此处输入图片说明

回答by scbojer

You can not exclude these since Notes and Reminders are not declared as UIActivitiesin the Apple Documentation. Only a problem as of iOS9 and hopefully Apple will provide this option. The declared UIActivities until this moment are:

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

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

回答by TimLR

Anybody stumbling in this post in 2019. The key for the Reminders extension changed with iOS 13 and is now:

任何人都在 2019 年在这篇文章中跌跌撞撞。提醒扩展的关键在 iOS 13 中发生了变化,现在是:

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

回答by test ing

Thank you for this! On xcode 8.1, swift 3, I was able to use to get:

这次真是万分感谢!在 xcode 8.1、swift 3 上,我能够使用:

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

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

回答by mm282

For Swift3+, there is no need for any Private API hacks. Simply use the public "excludedTypes" array on the UIActivityViewController. As there is still no UIActivityType for these (as they're Apple's built extensions), you need to refer to it via String. You could use this format for any third-party sharing extensions too.

对于 Swift3+,不需要任何私有 API hack。只需使用 UIActivityViewController 上的公共“excludedTypes”数组。由于这些仍然没有 UIActivityType(因为它们是 Apple 的内置扩展),您需要通过 String 引用它。您也可以将此格式用于任何第三方共享扩展。

e.g.

例如

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)

回答by eirik

Only way I have found is to create your own custom activities, pass parameters to them directly (not through the activity sheet) and then pass some random variable (not String, URL, Image) through the activity sheet.

我发现的唯一方法是创建您自己的自定义活动,直接将参数传递给它们(而不是通过活动表),然后通过活动表传递一些随机变量(不是字符串、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];

But then again, why would you want to use the ActivityViewController in the first place if you can't use any of the functionality... Hopefully there will be a better solution soon

但是话又说回来,如果您不能使用任何功能,为什么要首先使用 ActivityViewController...希望很快会有更好的解决方案

回答by Johannes Eichler

I could not send _shouldExcludeActivityType to Super as recommended by Matteo Pacini, but this is how I could come around this:

我无法按照 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];

 }