UIActivityShareDemo
UIActivityShareDemo
前言
之前在app内做跨app分享内容时,一般都会引入各种常见三方app的开发sdk,或者使用已经集成了各种三方分享的sdk如友盟啥的,但是现在越来越多的app开始使用苹果系统自带的分享功能,其中用到的类是UIActivityViewController
demo:
https://github.com/eye1234456/UIActivityViewControllerShareDemo
[站外图片上传中...(image-26b5f8-1648016233691)]
[站外图片上传中...(image-920e3f-1648016233691)]
一、普通使用方式
优点:调用简单,系统会自动根据分享的内容展示不同的UI样式及可分享的三方app和系统功能
缺点:展示出的系统UI弹窗内容固定,自定义差
- (void) showNormalActivityShare {
NSArray *activityItems = @[];
// 分享的是普通文本
activityItems = @[@"hello world"];
// 分享的是链接
//activityItems = @[[NSURL URLWithString:@"http://www.baidu.com"]];
// 分享的是图片
//activityItems = @[[UIImage imageNamed:@"xxx"]];
// 分享多个内容
//activityItems = @[[UIImage imageNamed:@"xxx"],[NSURL URLWithString:@"http://www.baidu.com"],@"hello world"];
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
__weak typeof(self) weakself = self;
activityVC.completionWithItemsHandler = ^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
if (activityType == nil && activityError == nil && completed == NO) {
NSLog(@"关闭分享弹窗");
}else if (activityType != nil && completed) {
// 分享成功
}else if (activityType != nil && activityError != nil) {
// 操作失败];
}else if (activityType != nil && completed == NO) {
// 操作失败
// 备忘录取消操作
}else {
}
};
[self presentViewController:activityVC animated:YES completion:^{
}];
}
二、LinkPresentation
、LPLinkMetadata
自定义分享头部的icon、主标题、子标题方式
优点:调用相对复杂,但能自定义头部的icon、主标题、子标题,适合大部分应用常见
缺点:相对复杂
原理:对默认分享的字符串、链接或图片等内容进行下包装,分享一个包装的内容,包装的类要实现UIActivityItemSource
协议
具体实现如下:
1、UI及数据model
@interface ShareModel : NSObject
/// 用于展示分享弹出顶部左侧的图片
@property(nonatomic, strong) UIImage * __nullable showIcon;
/// 用于展示分享弹窗顶部的大标题
@property(nonatomic, copy) NSString * __nullable showTitle;
/// 用于展示分享弹出顶部大标题下面的小标题
@property(nonatomic, copy) NSString * __nullable showSubTitle;
/// 真正分享的内容(如果没有配置show的三个字段,直接使用data进行自动分享展示)
/// NSURL、NSString、UIImage。。。
@property(nonatomic, strong) id data;
@end
@implementation ShareModel
@end
2、封装的实现UIActivityItemSource
分享Model
#import <UIKit/UIKit.h>
#import "ShareModel.h"
NS_ASSUME_NONNULL_BEGIN
@interface ShareViewModel : NSObject
@property(nonatomic, strong) ShareModel *model;
+ (instancetype)viewModelWithModel:(ShareModel *)model;
@end
NS_ASSUME_NONNULL_END
#import "ShareViewModel.h"
#import <UIKit/UIKit.h>
#import <LinkPresentation/LPLinkMetadata.h>
@interface ShareViewModel() <UIActivityItemSource>
@end
@implementation ShareViewModel
+ (instancetype)viewModelWithModel:(ShareModel *)model {
ShareViewModel *vm = [ShareViewModel new];
vm.model = model;
return vm;
}
#pragma mark - UIActivityItemSource protocol procedures to support sharesheet
/**
* 告诉系统分享的类型同类型的数据
*/
- (id)activityViewControllerPlaceholderItem:(UIActivityViewController *)activityViewController
{
return self.model.data;
}
/**
* 真正操作时的回调,表示要操作什么数据
*/
- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{
// 真正分享的内容
return self.model.data;
}
/**
* UIActivityViewController弹窗上展示的icon、主标题、子标题配置
*/
- (LPLinkMetadata *)activityViewControllerLinkMetadata:(UIActivityViewController *)activityViewController API_AVAILABLE(ios(13.0)){
LPLinkMetadata * metaData = [[LPLinkMetadata alloc] init];
// 只有分享的是URL或UIImage时,设置title才生效
// text时,一直固定显示Plain Text
if (self.model.showTitle) {
metaData.title = self.model.showTitle;
}
if (self.model.showSubTitle) {
metaData.originalURL = [NSURL fileURLWithPath:self.model.showSubTitle];
}
// 设置icon
if (self.model.showIcon) {
UIImage *iconImage = self.model.showIcon;
NSItemProvider *iconProvider = [[NSItemProvider alloc] initWithObject:iconImage];
metaData.iconProvider = iconProvider;
}
return metaData;
}
@end
3、真正分享
- (void)showCustomActivityShare {
NSArray *activityItems = @[];
// 分享的是普通文本,指定icon、主标题、子标题、分享的文本
ShareModel *originShareTextModel = [ShareModel modelWithShowIcon:icon showTitle:@"主标题" showSubTitle:@"子标题" data:shareText];
ShareViewModel *wrapShareShareTextModel = [ShareViewModel viewModelWithModel: originShareText];
activityItems = @[wrapShareShareTextModel];
// 分享的是链接
//ShareModel *originShareURLModel = [ShareModel modelWithShowIcon:icon showTitle:@"主标题" showSubTitle:@"子标题" data:[NSURL URLWithString:@"http://www.baidu.com"]];
//ShareViewModel *wrapShareShareURLModel = [ShareViewModel viewModelWithModel: originShareURLModel];
//activityItems = @[wrapShareShareURLModel];
// 分享的是图片
//activityItems = @[[UIImage imageNamed:@"xxx"]];
//ShareModel *originShareImageModel = [ShareModel modelWithShowIcon:icon showTitle:@"主标题" showSubTitle:@"子标题" data:[UIImage imageNamed:@"xxx"]];
//ShareViewModel *wrapShareShareImageModel = [ShareViewModel viewModelWithModel: originShareImageModel];
//activityItems = @[wrapShareShareImageModel];
// 分享多个内容
UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
__weak typeof(self) weakself = self;
activityVC.completionWithItemsHandler = ^(UIActivityType _Nullable activityType, BOOL completed, NSArray * _Nullable returnedItems, NSError * _Nullable activityError) {
if (activityType == nil && activityError == nil && completed == NO) {
NSLog(@"关闭分享弹窗");
}else if (activityType != nil && completed) {
// 分享成功
}else if (activityType != nil && activityError != nil) {
// 操作失败];
}else if (activityType != nil && completed == NO) {
// 操作失败
// 备忘录取消操作
}else {
}
};
[self presentViewController:activityVC animated:YES completion:^{
}];
}
}
过程中遇到的问题
1、在模拟器运行时,分享的弹窗一直展示英文,没有根据模拟器设置成中文展示成中文,这是需要在
Info.plist
里设置语言根据设备来展示
增加 Localized resources can be mixed
设置成YES
2、在分享图片时没有出现
存储图像
的操作,这是因为我创建的demo项目没有配置使用相册的权限,在Info.plist
里配置下就好了
增加 Privacy - Photo Library Additions Usage Description
设置成$(DISPLAY_NAME)需要你的同意,才能添加图片到相册
增加 Privacy - Photo Library Usage Description
设置成$(DISPLAY_NAME)想要访问您的相册,请允许
[站外图片上传中...(image-73c2a3-1648016233691)]
网友评论