由于iOS 擁有Airdrop的便捷式分享,以及越加復雜化的社交生態圈,越來越多的項目直接使用系統自帶的UIActivityViewController 達成社交化分享,并且進行一些列的自定義操作,方便的處理分享功能。剛好項目中有用到,一直以為很簡單的東西還是踩了不少的坑,于是拿出來與大家分享下。
簡單實現
- 系統自帶的Facebook,Twitter分享,國內有墻的存在,無法喚起app分享,因此使用自定義處理,方便兼容。
- 其他使用用戶安裝的APP自帶的分享extension足以。
自定義UIActivity
- 就是顯示在分享中的(UIActivityCategoryAction)第二行(UIActivityCategoryShare)第一行,可自定義顯示樣式(圖標、文字)
- 需要實現系統hook方法
-
activityVC.excludedActivityTypes
屬性,過濾自定義實現的分享type 比如activityVC.excludedActivityTypes = @[UIActivityTypePostToFacebook,UIActivityTypePostToTwitter];
- (void)performActivity 點擊事件實現
- 保存shareItems
- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { self.shareItems = activityItems; return YES; }
最終方案:自定義分享使用富媒體(圖片,鏈接、標題共存),Airdrop以及系統其他APP分享 只使用鏈接
- 關鍵方法
YSShareManager.h
中
// 根據初始化方式 保存臨時變量,以實現富媒體分享
@property (copy ,nonatomic,readonly)NSString *imageUrl;
@property (copy ,nonatomic,readonly)NSString *shareText;
@property (strong ,nonatomic,readonly)UIImage *shareImage;
@property (strong ,nonatomic,readonly)NSURL *shareUrl;
/**
適應Airdrop 分享最低層傳遞富媒體 中層action以及Airdrop只傳遞URL
@param imgUrl image地址
@param text 文本
@param urlStr 鏈接 不能為空
*/
+ (void)shareWithImageUrl:(nullable NSString*)imgUrl
text:(nullable NSString *)text
url:(nonnull NSString *)urlStr;
/**
清除臨時儲存的變量
*/
+ (void)clearShareKit;
-
YSShareManager.m
中
UIActivityViewControllerCompletionWithItemsHandler myBlock = ^(NSString *activityType,BOOL completed,NSArray *returnedItems,NSError *activityError) {
NSLog(@"activityType :%@", activityType);
if (completed) {
[FBSDKAppEvents logEvent:[NSString stringWithFormat:@"share_Success_%@",activityType]];
}
else {
[FBSDKAppEvents logEvent:[NSString stringWithFormat:@"share_Failed_%@",activityType]];
}
分享反饋中清空臨時保存的變量
[self clearShareKit];
};
使用方式
初始化
- 在appdelegate中或者在分享所在控制器實現添加對應的自定義分享
/**
添加制定類型分享 控制分享處理方式
@param option 類型枚舉 單個添加
@param perform 分享動作預設(要做啥子事情)
*/
+ (void)configShareKitAddOneActivityWithType:(YSShareOptionType)type
handleBlock:(SharePerform)perform;
/**
自己去實現 自定義分享 優先級比較上面的type高 兩者共存 自定義UIActivity子類使用此方法
@param activities 自定義分享實例
*/
+ (void)configShareKitWithCustomActivities:(nullable NSArray <UIActivity *>*)activities;
- 在回調函數中選擇使用相應的所需參數,自定義實現規則
YSWeakSelf(self);
[YSShareManager configShareKitAddOneActivityWithType:YSShareOptionTypeFaceBook handleBlock:^(NSArray * _Nonnull shareItems) {
[weakself shareToFaceBookWithItems:shareItems];
}];
- 舉個栗子
在我們項目中Home頁面加載后初始化分享配置
- (void)shareToFaceBookWithItems:(NSArray *)shareItems
{
//判斷服務是否可用
NSString *shareText = [BGLShareManager shareManager].shareText;
NSURL *shareURL = [BGLShareManager shareManager].shareUrl;
UIImage *shareImg = [BGLShareManager shareManager].shareImage;
[FBSDKAppEvents logEvent:@"Share to Facebook"];
......
}
在詳情頁發起分享
- (void)clickShareBtnAct:(id)sender{
// 適配iPad的分享
[BGLShareManager shareManager].sharePositionView = sender;
NSString *imageUrl = [_bannerImageUrlArr objectAtIndex:_bigImageShowView.currentItemIndex];
[BGLShareManager shareWithImageUrl:imageUrl text:_pName url:urlStr];
}
爬過的坑
關于Airdrop
不支持圖片和 URL 、文字 多種媒體同時傳遞
單一傳遞圖片時,直接保存到圖片瀏覽器
單一傳遞URL時,默認打開瀏覽器,可以使用APP的scheme或者短鏈接定向打開應用 ,使用
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
可以接收URL,進行內部處理單一傳遞NSString時 自動轉換為txt 使用app有注冊txt格式app列表打開
針對iPad
由于顯示樣式完全不同于手機,需要單獨處理,發起分享前設置sharePositionView
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:activityVC animated:YES completion:nil];
}else{
UIPopoverPresentationController *popover = activityVC.popoverPresentationController;
if (popover) {
popover.sourceView = [BGLShareManager shareManager].sharePositionView;
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
}
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:activityVC animated:YES completion:NULL];
}
短信分享界面不顯示取消按鈕
項目中可能存在第三方文件
UINavigationController+FDFullscreenPopGesture.m
使用了runtime
- 解決方案1 :一刀切,這個第三方庫已經不再實用新系統
- 解決方案2 :修改,刪除了pod管理這個第三庫,手動修改部分過濾條件
- (void)fd_pushViewController:(UIViewController *)viewController animated:(BOOL)animated { //過濾MessageUI,并且添加取消按鈕 if ([self isKindOfClass:[MFMessageComposeViewController class]]) { [self fd_pushViewController:viewController animated:animated]; [[self.viewControllers lastObject] navigationItem].rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(dismissModal:)]; return; } }
分享功能雖不復雜,但著實資料無多,大多復制粘貼,不如真實使用之后的實踐。文采有限,希望君閱之有所收獲。