UIActivityShareDemo
UIActivityShareDemo
Prefacio
En el pasado, al compartir contenido entre aplicaciones dentro de una aplicación, generalmente introducíamos varios SDK de desarrollo de aplicaciones de terceros comunes o usábamos SDK que han integrado varios recursos compartidos de terceros, como Umeng, pero ahora cada vez hay más aplicaciones que están comenzando. Usar la función de compartir que viene con el sistema Apple. Las clases utilizadas sonUIActivityViewController
demostración:
https://github.com/eye1234456/UIActivityViewControllerShareDemo
[Se están subiendo fotos fuera del sitio...(image-26b5f8-1648016233691)]
[Se están subiendo fotos fuera del sitio...(image-920e3f-1648016233691)]
1. Uso ordinario
Ventajas: la llamada es simple y el sistema mostrará automáticamente diferentes estilos de interfaz de usuario y aplicaciones de terceros y funciones del sistema que se pueden compartir según el contenido compartido.
Desventajas: la ventana emergente de la interfaz de usuario del sistema que se muestra tiene contenido fijo y una personalización deficiente.
- (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:^{
}];
}
2. LinkPresentation
Cómo LPLinkMetadata
personalizar el ícono, el título principal y el subtítulo del encabezado para compartir
Ventajas: La llamada es relativamente complicada, pero el ícono, el título principal y el subtítulo del encabezado se pueden personalizar, lo cual es adecuado para las aplicaciones más comunes.
Desventajas: relativamente complejo
Principio: empaquete las cadenas, enlaces, imágenes y otro contenido compartido predeterminado, comparta un contenido empaquetado y la clase empaquetada debe implementar el UIActivityItemSource
protocolo.
La implementación específica es la siguiente:
1. UI y modelo de datos
@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
UIActivityItemSource
2. Modelo de intercambio de implementación encapsulado
#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. Compartir de verdad
- (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:^{
}];
}
}
Problemas encontrados durante el proceso.
1. Cuando el simulador se está ejecutando, la ventana emergente para compartir siempre se muestra en inglés y no en chino según la configuración del simulador, lo que requiere configurar el
Info.plist
idioma en el simulador para que se muestre según el dispositivo.
Agregar Localized resources can be mixed
configuraciones aYES
2. No hay ninguna operación al compartir imágenes
存储图像
. Esto se debe a que el proyecto de demostración que creé no tiene permiso para usar el álbum de fotos.Info.plist
Simplemente configúrelo en
Agregar Privacy - Photo Library Additions Usage Description
configuraciones a$(DISPLAY_NAME)需要你的同意,才能添加图片到相册
Agregar Privacy - Photo Library Usage Description
configuraciones a$(DISPLAY_NAME)想要访问您的相册,请允许
La representación final es la siguiente:
NSString *testToShare = @"Fondo de pantalla AI HD";
// NSURL *urlToShare = [NSURL URLWithString:@"http://www.baidu.com"];
// UIImage *imageToShare = imagen;
// NSArray *actividadItems = @[testToShare,imageToShare,urlToShare];
// UIImage *imageToShare = imagen;
// NSArray *actividadItems = @[imageToShare];
NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary];
//Obtiene la matriz de todos los nombres de iconos en la aplicación
NSArray *iconsArr = infoDict[@"CFBundleIcons"][@"CFBundlePrimaryIcon"][@"CFBundleIconFiles"];
//Obtiene el nombre del último icono
NSString *iconoApellido;
si (iconsArr.count > 0) {
iconLastName = [iconsArr últimoObjeto];
}
más {
iconLastName = infoDict[@"CFBundleIcons"][@"CFBundlePrimaryIcon"][@"CFBundleIconName"];
}
UIImage *icono = [UIImage nombre de imagen:iconoApellido];
NSArray *actividadItems = @[];
// Lo que se comparte es texto normal, especifica el icono, título principal, subtítulo y texto compartido.
ShareModel *originShareTextModel = [ShareModel modelWithShowIcon:icon showTitle:@"AI HD Wallpaper" showSubTitle:@"Wallpaper APP actualizado todos los días" data:image];
ShareViewModel *wrapShareShareTextModel = [ShareViewModel viewModelWithModel: originShareTextModel];
artículos de actividad = @[wrapShareShareTextModel];
UIActivityViewController *activityVc = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities: nil ];
ActivityVc.excludedActivityTypes = @[UIActivityTypePrint,UIActivityTypeCopyToPasteboard,UIActivityTypeAssignToContact,UIActivityTypeSaveToCameraRoll];
ActivityVc.completionWithItemsHandler = ^(UIActivityType _Nullable ActivityType, BOOL completado, NSArray * _Nullable ReturnItems, NSError * _Nullable ActivityError) {
if (tipo de actividad == nil && error de actividad == nil && completado == NO ) {
// NSLog(@"Cerrar la ventana emergente para compartir");
}
else if (tipo de actividad! = nulo && completado) {
//Compartir exitosamente
}
else if (tipo de actividad! = nil && error de actividad! = nil ) {
// operación fallida];
}
else if (tipo de actividad! = nulo && completado == NO ) {
// operación fallida
//Operación de cancelación de nota
}
más {
}
};
[ self presentViewController:activityVc animado: SÍ finalización: nulo ];