您的位置:首页 > 移动开发 > IOS开发

iOS8扩展插件开发配置

2015-07-27 15:16 567 查看

http://blog.csdn.net/phunxm/article/details/42715145

一.iOS8扩展插件概述

WWDC14除了发布了OS X v10.10和switf外,iOS8.0也开始变得更加开放了。说到开放,当然要数应用扩展(App Extension)了。顾名思义,应用扩展允许开发者扩展应用的自定义功能和内容,能够让用户在使用其他应用程序时使用该项功能,从而实现各个应用程序间的功能和资源共享。可以将扩展理解为一个轻量级(nimble
and lightweight)的分身。

以下为常见的三类插件:
Target Type
Extension point identifier
Scenarios
Today Extension
com.apple.widget-extension
系统通知栏下拉显示
Share Extension
com.apple.share-services
Host App(照片、Safari、邮件、语音等)分享菜单第一行
Action Extension(UI)
com.apple.ui-services
Host App(照片、Safari、邮件、语音等)分享菜单第二行
下图为iPhone/iOS8中的【照片】分享:



例如【微信】最多支持分享9张(NSExtensionActivationSupportsImageWithMaxCount=9)照片给好友或到朋友圈。

二.插件工作机制

1.插件只能与Host App通过上下文直接通信





2.插件可通过共享资源区与Containing App间接通信





3.Host App-Extension-Containing App工作流程

Host App通过点击系统分享菜单中的插件图标调起扩展程序——Share/ActionExtension (*.appex)。
iOS系统(Host App)通过扩展上下文(NSExtensionContext)向Share/ActionExtension传递欲分享的数据。
Share/Action Extension提取数据并序列化到以AppGroup ID标识的共享资源区NSUserDefaults/AppGroup Container(containerURLForSecurityApplicationGroupIdentifier)中。
Share/Action Extension通过URL
Scheme呼起ContainingApp,同时插件通过上下文向iOS系统(HostApp)发出request completion通知,以便返回到Host App(iOS系统会dismiss插件UIViewController)。
Containing App通过App Group ID从NSUserDefaults/containerURL中读取分享过来的数据,并对分享数据进行后续处理。

由此可见,扩展插件将Host App与Containing App勾搭起来,而App Group Container则架起了数据交互的鹊桥。

这里需要注意的是,在iOS 8.0中,只有Today Extension才支持直接调用NSExtensionContextopenURL:completionHandler:打开URL链接;Share/Action
Extension要想实现URL Scheme,只能创建一个Sink UIWebVew对URL进行loadRequest实现曲线救国(所谓“Sink”是指隐而不显,例如frame=CGRectZero)。

4.插件的UI形态

插件在UI上以UIViewController模式存在,被parentViewController(Host App)以模态窗口形式弹出(present as modal viewController)。

插件工程在Info.plist的NSExtension中通过NSExtensionMainStoryboard指定UI视图入口。当然,如果不想使用storyboard,也可以使用NSExtensionPrincipalClass指定自定义UIViewController子类名(也可以封装到UINavigationController)。

注意:

新建Extension Target后(Deployment Target≥8.0),需在Build Settings|Architectures|Valid Architectures中增加arm64
初始安装Containing App时,扩展插件并未使能,需要到【更多】中打开开关。

三.插件的局限性

以下文字节选自《App Extension Programming Guide》,主要列举了插件的局限性,以知其可为不可为。

--------------------------------------------------------------------------------

1.Design a Streamlined UI

An extension`s UI should be simple, restrained,
and focused on facilitating a single task.
To improve performance and the user`s experience, avoid including extraneous UI
that doesn`t support your extension`s main task.

2.Optimize Efficiency and Performance

(1)App extensions should feel nimble and lightweight to
users.

Design your app extension to launch quickly, aiming
for well under one second.
An extension that launches too slowly is terminated by
the system.

(2)Memory limits for running app extensions are significantly lower than
the memory limits imposed on a foreground app.

On both platforms, the system may aggressively terminate extensions
because users want to return to their main goal in the host app.
Some extensions may have lower memory limits than others.

(3)Your app extension doesn`t own the main run loop, so it`s crucial
that you follow the established rules for good behavior in main runloops.

For example, if your extension blocks the main runloop,
it can create a bad user experience in another extension or app.

(4)Keep in mind that theGPU is a shared resource in the system.

App extensions do not get top priority for shared resources; for example, a Today widget that runs a graphics-intensive game might give users a bad experience. The
system is likely to terminate such an extension because of memory pressure.
Functionality that makes heavy use of system resources is appropriate for an app, not an app extension.

--------------------------------------------------------------------------------

由此可见,iOS系统对插件要求简洁至上:UI启动要快、内存消耗要少、runloop执行耗时要短。

iOS系统对插件的限制决定了开发的插件必须轻量,发点Twitter/微博分享、小图片文件分享、URL跳转还是可以的;奢望丰富绚丽的UI或者用来传大文件等大动作是不合适的。

当然,如果希望扩展(即使退出)执行长时间任务(比如上传/下载),可以使用NSURLSession来创建一个上传/下载session,并初始化一个后台上传/下载任务。

注意:

Apple也限制了扩展在API使用方面的权限,在扩展中禁用的API原型声明被标上了NS_EXTENSION_UN***AILABLE宏。例如:

+ (UIApplication*)sharedApplication NS_EXTENSION_UN***AILABLE_IOS;

对sharedApplication的限制实际上就是不让插件直接获取访问宿主应用(Host App的UIApplication)对象。

四.Share/Action扩展插件支持的媒体类型配置

Info.plist中的NSExtension|NSExtensionAttributes|NSExtensionActivationRule
Dictionary可以配置插件支持的媒体类型及数量:

iOS扩展插件支持媒体类型配置键
描述
配置
说明
NSExtensionActivationSupportsAttachmentsWithMaxCount
附件最多限制
20
附件包括下面的File、Image和Movie三大类,单一、混选总量不超过20
NSExtensionActivationSupportsAttachmentsWithMinCount
附件最少限制
上面非零时,default=1
默认至少选择1个附件,【分享】中才显示扩展插件图标
NSExtensionActivationSupportsFileWithMaxCount
文件最多限制
20
文件泛指除Image/Movie之外的附件,例如【邮件】附件、【语音备忘录】等。

单一、混选均不超过20。
NSExtensionActivationSupportsImageWithMaxCount
图片最多限制
20
单一、混选均不超过20
NSExtensionActivationSupportsMovieWithMaxCount
视频最多限制
20
单一、混选均不超过20
NSExtensionActivationSupportsText
文本类型
default=0
默认不支持文本分享,例如【备忘录】
NSExtensionActivationSupportsWebURLWithMaxCount
Web链接最多限制
default=0
默认不支持分享超链接,例如【Safari】
NSExtensionActivationSupportsWebPageWithMaxCount
Web页面最多限制
default=0
默认不支持Web页面分享,例如【Safari】
宿主应用(Host App)提供一个上下文(NSExtensionContext)向扩展(appex)传递数据,包含了待处理的数据(inputItems)。其传递的数据是一组NSExtensionItem对象,其中要分享的图片、视频、URL等附件就保存在NSExtensionItem的attachments数组中。

关于UTIs,参考UniformType Identifiers
Reference | System-Declared Uniform Type Identifiers。
媒体类型
文件UTI
图片(public.image)
kUTTypeImage

kUTTypeJPEG

kUTTypePNG

kUTTypeGIF

kUTTypeTIFF

kUTTypeBMP

kUTTypeICO
视频(public.movie)
kUTTypeMovie

kUTTypeQuickTimeMovie

kUTTypeMPEG

kUTTypeMPEG4

kUTType***IMovie

@"public.3gpp"

@"com.real.realmedia"

@"com.microsoft.windows-media-wmv"

@"com.microsoft.advanced-systems-format"
音频(public.audio)
kUTTypeAudio

kUTTypeMP3

kUTTypeMPEG4Audio

kUTTypeWaveformAudio

@"com.microsoft.windows-media-wma"
文档
kUTTypePDF

@"com.microsoft.word.doc"

@"com.microsoft.excel.xls"

kUTTypePresentation

@"com.microsoft.powerpoint.ppt"

@"com.apple.keynote.key"
压缩包
kUTTypeZipArchive

kUTTypeGNUZipArchive

kUTTypeBzip2Archive

@"public.tar-archive"

@"org.gnu.gnu-zip-tar-archive"

五.插件与Containing App的App
Group证书配置

Containing App及其Extension是通过以App Group ID标识的共享资源区—App
Group Container
来实现数据共享的。

Containing App及其Extension的App ID必须是Explicit,且Extension App ID必须以Containing App
ID为Prefix/Seed,并且配置到同一App Group下。

App ID配置到Info.plist的BundleIdentifier中;App Group在target的【Xcode
Target|Capabilities】中启用,配置到【Xcode Target|Build Settings|Code Signing|Code Signing Entitlements】中的*.entitlements文件的com.apple.security.application-groups

键中。
证书和Provisioning Profile的申请以及Code Signing配置流程同以前普通的App,详情请参考《iOS开发证书要点详解》。

六.Containing App的Build Phases配置(embed app extensions)

Containing App 的【Xcode target|BuildPhases|Target Dependencies】中可以添加或移除插件target。

Containing App 的【Xcode target|BuildPhases|Embed App Extensions】下Destination为Plugins中可以添加或移除插件product(*.appex)。

注意:默认了勾选“Copy only when installing”,表示从AppStore安装(包括升级覆盖)时才拷贝插件。Xcode连接真机调试时,需取消该改项,否则系统【分享】菜单中不会出现插件!



参考:

《App
Extension Programming Guide》/《App Extension编程指南

《App
Extensions for iOS 8 in Depth》

《iOS8
Extensions》《iOS8通知中心扩展***入门

iOS
8.0 Action Extension icon is blank on device which fixed in iOS 8.1
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: