iOS应用扩展:如何实例化UIActivity子类使其出现在分享列表?
解决自定义UIActivity不显示在分享列表的问题
看起来你是想让自定义的分享活动出现在系统或APP的分享面板里,但因为没正确配置实例化逻辑导致它没被调用。我来一步步帮你梳理解决思路:
1. 先明确两种分享扩展的区别
首先得搞清楚:如果是要在系统自带APP(比如照片、Safari)的全局分享列表里出现你的扩展,单纯子类化UIActivity是不够的——这种场景下你应该创建Action Extension。但如果你是想在自己APP的分享面板里添加自定义活动,那UIActivity子类的方式是正确的,下面分场景说明:
场景一:在自己APP的分享面板里显示自定义UIActivity
第一步:补全myActivity子类的核心方法
UIActivity子类必须实现几个关键方法,系统才会识别并展示它:
#import "myActivity.h" @interface myActivity () @property (nonatomic, strong) UIImage *sharedImage; @end @implementation myActivity // 必须返回唯一的活动类型标识 - (NSString *)activityType { return @"com.yourcompany.yourapp.myImageShareActivity"; } // 分享列表里显示的名称 - (NSString *)activityTitle { return @"我的自定义分享"; } // 分享列表里显示的图标(建议用60x60pt纯色图,系统自动处理圆角) - (UIImage *)activityImage { return [UIImage imageNamed:@"custom-activity-icon"]; } // 判断当前分享内容是否支持你的活动(这里只支持图片) - (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { for (id item in activityItems) { if ([item isKindOfClass:[UIImage class]] || ([item isKindOfClass:[NSURL class]] && [[item pathExtension] isEqualToString:@"png"])) { return YES; } } return NO; } // 准备处理分享内容,保存需要的资源 - (void)prepareWithActivityItems:(NSArray *)activityItems { for (id item in activityItems) { if ([item isKindOfClass:[UIImage class]]) { self.sharedImage = item; NSLog(@"已获取到分享的图片"); break; } } } // 执行你的分享逻辑,完成后必须告诉系统结束 - (void)perform { NSLog(@"开始处理分享图片:%@", self.sharedImage); // 这里写你的业务逻辑,比如跳转到APP内处理图片 [self activityDidFinish:YES]; } @end
第二步:实例化并传入UIActivityViewController
在你触发分享的代码里,需要把自定义Activity的实例传给分享控制器的applicationActivities参数,系统才会把它加入分享列表:
// 假设你要分享的图片是targetImage UIImage *targetImage = [UIImage imageNamed:@"test-photo"]; NSArray *activityItems = @[targetImage]; // 实例化你的自定义Activity myActivity *customActivity = [[myActivity alloc] init]; // 创建分享面板 UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:@[customActivity]]; // iPad适配(如果需要) if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { activityVC.popoverPresentationController.sourceView = self.view; activityVC.popoverPresentationController.sourceRect = CGRectMake(self.view.center.x, self.view.center.y, 0, 0); } // 展示分享面板 [self presentViewController:activityVC animated:YES completion:nil];
场景二:在系统APP的全局分享列表里出现(比如照片APP)
如果是想让用户在照片APP里点分享时,你的扩展出现在列表,那应该用Action Extension:
- 在Xcode里点击
File > New > Target,选择Action Extension,配置名称后创建 - 打开Extension的
Info.plist,修改NSExtensionActivationRule,指定支持图片类型:<key>NSExtensionActivationRule</key> <dict> <key>NSExtensionActivationSupportsImageWithMaxCount</key> <integer>1</integer> </dict> - 在Extension的主ViewController里,实现
didSelectExtensionItem方法处理分享的图片:- (void)didSelectExtensionItem:(NSExtensionItem *)item { for (NSItemProvider *provider in item.attachments) { if ([provider hasItemConformingToTypeIdentifier:(NSString *)kUTTypeImage]) { [provider loadItemForTypeIdentifier:(NSString *)kUTTypeImage options:nil completionHandler:^(id<NSSecureCoding> _Nullable item, NSError * _Nullable error) { if ([item isKindOfClass:[UIImage class]]) { UIImage *sharedImage = item; NSLog(@"收到系统分享的图片:%@", sharedImage); // 这里处理你的业务逻辑 } }]; } } [self extensionContext].completeRequestReturningItems:nil completionHandler:nil; }
常见排查点
- 检查
activityImage的图片是否符合要求:避免带圆角或复杂样式,系统会自动处理外观 - 确认
canPerformWithActivityItems返回YES,否则系统会隐藏你的活动 - 如果是Action Extension,确保
Info.plist的NSExtension配置没有语法错误
内容的提问来源于stack exchange,提问作者Laurent Crivello
相关产品推荐
相关产品推荐

