iOS原生分享【UIActivityViewController】

这篇博客真的拖了好久好久。这段时间被各种事情缠身(借口)。终于,能够好好整理一下最近的工作。切入正题,这次要讲的是在iOS客户端不使用第三方框架的前提下,实现分享的功能。该功能前人也造了很多轮子,本篇博客主要是结合自己在开发中遇到的一些情况对这个功能做个总结,与大家一起探讨。


简介

目前,我们用到的app几乎每一个都包含了分享的功能。实际开发中,大部分情况下使用都是基于第三方,如shareSDK,友盟等平台实现社交分享功能。使用第三方平台的可定制性高,但需要到每个平台去注册应用申请key并且引入API就很繁琐。相对而言,系统分享就简易了很多。

一、分享的内容

分享的内容可以是文字、图片、视频甚至是GIF。当然有些平台有限制。比如,微信朋友圈和微博是分享不了GIF和视频的。需要分享的内容实体放在一个数组里,下面一一介绍。

1. 图片+文字

- (void)shareImage
{
    NSString *textToShare = self.titleTextField.text;
 // load你要分享的图片,通过bundle或者沙盒,或者name
    UIImage *imageToShare = [UIImage xxxx];
    [self shareWithActivityItems: @[textToShare, imageToShare]];
}

2. 视频+文字

此处分享的是本地视频,self.moviePath是本地视频沙盒路径。上效果图。

视频分享弹窗.png

- (void)shareVideo
{
    NSString *textToShare = self.titleTextField.text;
    NSURL *urlToShare = [NSURL fileURLWithPath:self.moviePath];
    [self shareWithActivityItems: @[textToShare,urlToShare]];
}

3. GIF+文字

这种类型的例子真的太少了。造好了轮子,分享到微信成功,见证奇迹的时刻了。不料,打开却是静图。排查了各种原因,也尝试了其他造轮子的方法。终于得出是因为: 图片太大了。合成GIF的时候,没有对图片进行处理,图片过大导致分享出去打开是静图而在PC端可以正常打开。

- (void)shareGIF
{
    NSString *textToShare = self.titleTextField.text;
    NSURL *urlToShare = [NSURL fileURLWithPath:self.gifPath];
    [self shareWithActivityItems: @[textToShare,urlToShare]];
}

二、弹出分享框

很明显上面的shareWithActivityItems()就是弹出分享框的方法了。具体如下。

- (void)shareWithActivityItems:(NSArray *)activityItems
{
    UIActivityViewController *activityVC = [[UIActivityViewController alloc]initWithActivityItems:activityItems applicationActivities:[self setupActivityWithActivityItems:activityItems]];
    // 根据需要指定不需要分享的平台
    activityVC.excludedActivityTypes = @[UIActivityTypeMail,UIActivityTypePostToTwitter,UIActivityTypeMessage,UIActivityTypePrint,UIActivityTypeCopyToPasteboard,UIActivityTypeAssignToContact,UIActivityTypeAddToReadingList,UIActivityTypePostToFlickr,UIActivityTypePostToVimeo,UIActivityTypePostToTencentWeibo,UIActivityTypeAirDrop,UIActivityTypeOpenInIBooks];
    // >=iOS8.0系统用这个方法
    activityVC.completionWithItemsHandler = ^(NSString *activityType,BOOL completed,NSArray *returnedItems,NSError *activityError)
    {
        if (completed) { // 确定分享
        }
        else {
        }
    };
    [self presentViewController:activityVC animated:YES completion:nil];
}

三、选择分享的平台

一般情况下,系统分享会列出手机上能够支持该分享内容的平台。如微信,QQ,新浪微博,等等。当然你也可以在更多里边进行控制这些平台的展示与否。如图,来自简书中包含的系统分享。


系统分享弹窗.PNG

可以看到有两行显示,分别表示分享和操作。当然,你可以指定。综上,就可以完成分享的功能了。如果您需要自定义分享的平台,您可以往下看。

typedef NS_ENUM(NSInteger, UIActivityCategory) {
    UIActivityCategoryAction,
    UIActivityCategoryShare,
} NS_ENUM_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;

四、自定义UIActivity

官方文档解释,UIActivity必须通过继承的方式来使用。大概步骤,网上还是很多轮子的。这里主要讲解一下细节部分。

- (void)performActivity
{
     if([self.type isEqualToString:ActivityServiceFackBook]) { 
        if([SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook]) {
            SLComposeViewController *composeVC = [SLComposeViewController composeViewControllerForServiceType:kShareFaceBook];
            [self shareActionWithVC:composeVC ShareType:self.type];
            [self.currentViewController presentViewController:composeVC animated:NO completion:nil];
        }
        else {
            [self showErrorText:@"没有安装FaceBook"];
        }
    }
    [self activityDidFinish:YES];
}

(void)performActivity调用这个方法执行具体的服务操作。比如,你自定义微信和新浪这服务。当你点击自定义服务的时候,会调用这个方法。所以你需要这个方法里判断你点击的具体服务是什么。前面我代码中演示的是点击facebook的例子。

如果自定义的服务实现分享视频。你可以按照以下操作。

- (void)shareActionWithVC:(SLComposeViewController *)composeVC
{
    // self.shareContexts 是在弹出分享框的时候传入的,可以参照上面的代码
    for (id obj in self.shareContexts) {
       if ([obj isKindOfClass:[NSURL class]]) { // 视频
            NSURL *urlToShare = (NSURL *)obj;
            if(urlToShare.absoluteString.length >0) { // 有视频
                [composeVC addURL:urlToShare];
            }
        }
}

综上,您就可以实现系统分享的功能了。欢迎讨论。

推荐阅读更多精彩内容