zoukankan      html  css  js  c++  java
  • iOS8扩展插件开发配置

    一.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_UNAVAILABLE宏。例如:

    + (UIApplication*)sharedApplication NS_EXTENSION_UNAVAILABLE_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

        kUTTypeAVIMovie

        @"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连接真机调试时,需取消该改项,否则系统【分享】菜单中不会出现插件

  • 相关阅读:
    ASP.NET Core 从入门到精通-资源收集导航
    【5分钟系列】计算机系统结构的定义
    C#反射与特性(九):全网最全-解析反射
    C#反射与特性(七):自定义特性以及应用
    C#反射与特性(六):设计一个仿ASP.NETCore依赖注入Web
    C#反射与特性(五):类型成员操作
    C#反射与特性(四):实例化类型
    C#反射与特性(三):反射类型的成员
    C#反射与特性(二):探究反射
    安卓TabLayout+ViewPager实现切页
  • 原文地址:https://www.cnblogs.com/feng9exe/p/7562508.html
Copyright © 2011-2022 走看看