Application Extension(三):Share Extension

Share Extension 简介

前两篇文章介绍了Application Extension运行原理Today Extension,本篇来介绍一下 Share Extension 创建和使用。
分享扩展给用提供一个方便的途径来分享内容,例如在某个带有分享按钮的应用中,用户可以选择一个分享扩展,来把要想分享的内容或者评论发布到自己的社交账号。

可以在iOS、macOS上创建分享扩展,在创建之前要注意:

  • 确保用户在使用你的分享扩展时,方便、快捷
  • 确保用户能够预览、编辑、配置要分享的内容
  • 在分享之前确认内容

创建 Share Extension

下面就来在iOS上创建一个分享扩展,就接着上篇的Today项目里面创建。
注意本例子使用的是 Xcode9,iOS 11。
新建 target

创建 Share Extension

创建之后Xcode默认的模板就可直接运行,在运行的时候可以选择运行主体应用Containing App,想要看到你的分享的扩展,需要另打开一个带有分享按钮的应用当做你的扩展的宿主应用Host App,在Host App中展开分享页面才能看到,要是看不到的话,点击More更多按钮,在里面打开就能看到。

最好直接选择分享扩展运行,方便我们调试,在选择分享扩展运行时,弹出个框选择一个iOS App来当做你的扩展的Host App,如下图所示:

例子选择打开系统的相册,运行打开相册,点击分享按钮,看到创建的扩展,点击就会弹出系统默认的编辑视图。

若是系统弹出的默认编辑视图不能满足你的需求,也可以不用系统默认的分享弹出框,完全自己实现一个编辑视图。

声明 Share Extension 支持的数据类型

使用Xcode创建 Share Extension 后,项目文件夹里默认生成的文件有 ShareViewController、Info.plist、storyboard。
Info.plist里面包含 Share Extension 的一些配置文件,值得注意的是 NSExtension 扩展描述字段,用来设置扩展的一些属性:

<key>NSExtension</key>
    <dict>
        <key>NSExtensionAttributes</key>
        <dict>
            <key>NSExtensionActivationRule</key>
            <string>TRUEPREDICATE</string>
        </dict>
        <key>NSExtensionMainStoryboard</key>
        <string>MainInterface</string>
        <key>NSExtensionPointIdentifier</key>
        <string>com.apple.share-services</string>
    </dict>

根据你的分享扩展的需要去添加对应键。
NSExtensionAttributes 是用来描述扩展的属性字段,里面包含了 NSExtensionActivationRule ,这个用来控制 Share Extension 或者 Action Extension 所能支持的分享的内容,默认的值是 TRUEPREDICATE 分享的内容都满足扩展需要,该分享扩展会一直在分享列表显示供用户使用。如果对分享的内容有所限制,例如微信、微博,最多能分享九张图,如果你的选择了多于九张图,则在分享列里就不会显示微信、微博的分享。想要添加限制,需要修改 NSExtensionActivationRule 对应的值为 dictionary,里面所能包含的键有AppExtensionKeys

包含了支持的最大、最小的内容个数、文件个数、图片个数、视频个数、链接个数等。例如下面的属性配置最大支持10张图片、1个视频、1个网页:

<key>NSExtensionAttributes</key>
    <dict>
        <key>NSExtensionActivationRule</key>
        <dict>
            <key>NSExtensionActivationSupportsImageWithMaxCount</key>
            <integer>10</integer>
            <key>NSExtensionActivationSupportsMovieWithMaxCount</key>
            <integer>1</integer>
            <key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
            <integer>1</integer>
        </dict>
    </dict>

如果不支持某特定的数据格式可设置值为0,或者从dictionary中移除对应的值。

处理 Share Extension 的数据

默认创建的ShareViewController 继承自SLComposeServiceViewController 。在ShareViewController中有个 didSelectPost 方法:

//用户点击发布post按钮后,调用此方法。
//默认状态会在该方法里面实现extensionContext 的 -completeRequestReturningItems:completionHandler:方法
//子类要覆盖此方法,从而能够根据上下文内容,来执行post操作
// 子类可以用super调用此方法来完成默认的行为; 如果一个子类不调用super,那么它必须手动调用extensionContext的completeRequestReturningItems:方法。
- (void)didSelectPost {
        //执行post 操作
        //获取分享的内容,发送请求
        //NSExtensionItem *inputItem = self.extensionContext.inputItems.firstObject;

        [self.extensionContext completeRequestReturningItems:@[] completionHandler:nil];

        //或者直接调用 [super didSelectPost]  默认状态下完成操作
}



NSExtensionContext 类型的属性,是宿主应用(Host App) 调起扩展所对应的上下文,里面的值包含了想要分享的图片、文字、网页等内容信息。

NSExtensionContext
  • 属性 inputItems : 该数组存储着容器应用传入给NSExtensionContext的NSExtensionItem数组。其中每个NSExtensionItem标识了一种类型的数据。
  • 方法 completeRequestReturningItems: 通知宿主应用的扩展已完成发布请求。调用此方法后,扩展视图会关闭,其中的items就是返回宿主应用中的数据项。
  • 方法 cancelRequestWithError: 通知宿主应用的扩展已取消请求。其中error为错误的描述信息。

NSExtensionItem类的结构如下:

NSExtensionItem

NSExtensionItem中的attachments属性,是一个附件数组,数组里的是NSItemProvider类型,其中包含了图片、视频、链接等内容。
要想获得 NSItemProvider 中的内容会使用到其类中的一个方法 loadItemForTypeIdentifier:options:completionHandler 加载typeIdentifier指定的资源,加载完成后会触发completionHandler。

所以 NSExtensionContext 上下文里的数据结构如下:


NSExtensionContext.png

从 NSItemProvider 中获取分享内容的方法,如下(获取分享的网页链接的数据):

    [self.extensionContext.inputItems enumerateObjectsUsingBlock:^(NSExtensionItem * _Nonnull extItem, NSUInteger idx, BOOL * _Nonnull stop) {
        [extItem.attachments enumerateObjectsUsingBlock:^(NSItemProvider * _Nonnull itemProvider, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([itemProvider hasItemConformingToTypeIdentifier:@"public.url"]) {
                [itemProvider loadItemForTypeIdentifier:@"public.url"
                                                options:nil
                                      completionHandler:^(NSURL *  _Nullable item, NSError * _Null_unspecified error) {
                                          //NSLog(@"url === %@", item);
            }
        }];
    }];

就这样一步步获取到要分享的内容,获取到内容后发送内容给服务器,Share Extension 可以通过与容器应用Containing App 共享数据,在Containing App中显示从 Host App 分享过来的数据。
(Extension和Containing App间共享数据,在上一篇文章Today Extension有介绍,同样的方法可以去查看,这里就不在赘述了)

简单的写了个小例子,效果如下:


Demo地址:https://github.com/MA806P/MYZAppExtension


Reference

App Extension Programming Guide - Today
http://www.jianshu.com/p/863ce6729455

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容