App Extensions - 创建应用程序扩展 - Creating an App Extension

当您准备开发应用程序扩展时,首先选择支持您想要方便的用户任务的扩展点。使用相应的Xcode应用程序扩展模板,并使用自定义代码和用户界面(UI)增强默认文件。优化并测试应用扩展程序后,您就可以在包含的应用程序中进行分发。

通过选择正确的延伸点开始开发

由于每个扩展点都针对定义明确的用户场景,因此您的第一个任务是选择支持您计划提供的功能类型的扩展点。这个选择很重要,因为它决定了您可以使用的API,在某些情况下,它确定了API的行为方式。

iOS和OS X中支持的扩展点及其Info.plist扩展点标识符键在NSExtensionPointIdentifier一节中描述。

选择对您的应用扩展程序有意义的扩展点后,请在包含的应用中添加新目标。添加应用扩展目标的最简单方法是使用Xcode模板,该模板提供为您的扩展点预配置的目标。

要向Xcode应用程序项目添加新目标,请选择“File”>“New”>“Target”。在新目标对话框左侧的侧栏中,选择iOS或OS X的应用程序扩展。在对话框右侧的窗格中,Xcode显示您可以选择的模板。例如,图3-1显示了可用于创建iOS应用程序扩展的模板。

图3-1 Xcode提供了几个可以使用的应用扩展模板

图片:../ Art / add_new_target_2x.png

选择模板并完成将目标添加到项目后,即使在自定义扩展代码之前,也应该能够构建和运行项目。当您基于Xcode模板构建扩展时,您将获得以.appex。结尾的扩展束。

屏幕快照 2019-06-02 下午10.34.38.png

关于64位架构的注意事项

应用扩展目标必须在其架构构建设置中包含arm64(iOS)或x86_64架构(OS X),否则App Store将拒绝该应用。当您创建新的应用程序扩展目标时,Xcode包含适当的64位体系结构及其“标准体系结构”设置。

如果您的包含应用程序目标链接到嵌入式框架,则应用程序还必须包含64位体系结构,否则App Store将拒绝该应用程序。

有关64位开发的详细信息,请参阅Cocoa Touch的64位转换指南Cocoa的64位转换指南,具体取决于您的目标平台。

在大多数情况下,您可以通过在“系统偏好设置”或“设置”中启用默认应用扩展程序,然后通过其他应用程 例如,您可以通过在Safari中打开网页,单击“共享”工具栏按钮,然后在显示的菜单中选择扩展名来测试OS X Share扩展。

检查默认应用程序扩展模板

每个应用扩展模板包括属性列表文件(即Info.plist文件),视图控制器类和默认用户界面,所有这些都由扩展点定义。默认视图控制器类(或主体类)可以包含应实现的扩展点方法的存根。

应用扩展程序目标的Info.plist文件标识扩展点,并可能指定有关扩展程序的一些详细信息。该文件至少包括NSExtension密钥以及扩展点指定的密钥和值的字典。例如,所需NSExtensionPointIdentifier密钥的值是扩展点的反向DNS名称,例如com.apple.widget-extension。以下是您在扩展程序NSExtension字典中可能会看到的一些其他键和值:

  • NSExtensionAttributes

    特定于扩展点的属性的字典,例如PHSupportedMediaTypes用于照片编辑扩展。

  • NSExtensionPrincipalClass

    模板创建的主视图控制器类的名称,例如SharingViewController。当Host App调用您的扩展时,扩展点将实例化此类。

  • NSExtensionMainStoryboard (仅限iOS扩展)

    扩展名的默认情节提要文件,通常命名为MainInterface

除了属性列表设置,模板可以默认设置一些功能。每个扩展点都可以定义对扩展点支持的任务类型有意义的功能。例如,iOS文档提供程序扩展包括com.apple.security.application-groups权利。

OS X应用扩展的所有模板com.apple.security.files.user-selected.read-only默认包括App Sandbox和权利。如果需要执行诸如使用网络或访问用户照片或联系信息之类的操作,您可能需要为扩展程序定义其他功能。

注意
通常,当用户授予包含应用程序访问其私有数据的权限时,包含应用程序中的所有扩展程序也会获得访问权限。

回应Host App的请求

正如您在了解应用程序扩展如何工作中所学到的,当用户在Host App中选择扩展并且Host App发出请求时,将打开应用程序扩展。在较高级别,您的分机根据用户的操作接收请求,帮助用户执行任务,以及完成或取消请求。例如,共享扩展程序从Host App接收请求,并通过显示其视图进行响应。用户在视图中撰写内容后,他们选择发布内容或取消帖子,扩展完成或取消相应的请求。

当Host App向应用程序扩展发送请求时,它会指定扩展上下文。对于许多扩展,上下文中最重要的部分是用户在扩展中时想要使用的项集。例如,OS X Share扩展的上下文可能包括用户想要发布的文本选择。

一旦Host App发出其请求(通常通过调用该[beginRequestWithExtensionContext:](https://developer.apple.com/documentation/foundation/nsextensionrequesthandling/1413395-beginrequestwithextensioncontext)方法),您的应用程序扩展就可以使用[extensionContext](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621411-extensioncontext)其主视图控制器上的属性来获取上下文。子视图控制器也可以通过链接访问此属性。

接下来,您使用[NSExtensionContext](https://developer.apple.com/documentation/foundation/nsextensioncontext)该类检查上下文并获取其中的项。通常,它可以很好地获取视图控制器[loadView](https://developer.apple.com/documentation/uikit/uiviewcontroller/1621454-loadview)方法中的上下文和项目,以便您可以在视图中显示信息。要获取扩展程序的上下文,您可以使用以下代码:

  1. NSExtensionContext *myExtensionContext = self.extensionContext;

特别感兴趣的是上下文对象的[inputItems](https://developer.apple.com/documentation/foundation/nsextensioncontext/1414827-inputitems)属性,它可以包含您的应用扩展需要使用的项目。该inputItems属性包含一个[NSExtensionItem](https://developer.apple.com/documentation/foundation/nsextensionitem)对象数组,每个对象都包含扩展可以处理的项。要从上下文对象中获取项目,您可以使用以下代码:

  1. NSArray *inputItems = myExtensionContext.inputItems;

每个NSExtensionItem对象都包含许多描述项目方面的属性,例如标题,内容文本,附件和用户信息。

请注意,该[attachments](https://developer.apple.com/documentation/foundation/nsextensionitem/1416690-attachments)属性包含与项目关联的媒体数据数组。例如,在与共享请求相关联的项目中,该attachments属性可能包含用户想要共享的网页的表示。

用户使用输入项目后(如果这样做是使用应用程序扩展的一部分),应用程序扩展通常会让用户在完成或取消任务之间做出选择。根据用户的选择,您可以调用[completeRequestReturningItems:completionHandler:](https://developer.apple.com/documentation/foundation/nsextensioncontext/1411301-completerequest)方法,可选地将NSExtensionItem对象返回到Host App或[cancelRequestWithError:](https://developer.apple.com/documentation/foundation/nsextensioncontext/1412773-cancelrequestwitherror)方法,返回错误代码。

重要

如果您的应用扩展程序调用该[completeRequestReturningItems:completionHandler:](https://developer.apple.com/documentation/foundation/nsextensioncontext/1411301-completerequest)方法,请completionHandler至少提供一个阻止,以便在系统要求时暂停您的应用扩展程序。有关详细信息,请阅读NSExtensionContext类参考中completionHandler有关此方法的块的文档。

在iOS中,您的应用扩展程序可能需要更多时间来完成可能冗长的任务,例如将内容上传到网站。在这种情况下,您可以使用[NSURLSession](https://developer.apple.com/documentation/foundation/urlsession)该类在后台启动传输。由于后台传输使用单独的进程,因此在您的扩展完成Host App的请求并终止后,传输可以作为低优先级任务继续进行。要了解有关NSURLSession在扩展程序中使用的详细信息,请参阅执行上传和下载

重要

虽然您可以设置后台URL上载或下载任务,但其他类型的后台任务(如支持VoIP或播放后台音频)不可用于扩展。

如果您UIBackgroundModes在应用扩展程序的Info.plist文件中包含该密钥,则App Store会拒绝该扩展程序。(要了解有关此密钥的更多信息,请参阅UIBackgroundModes。)

优化效率和性能

应用扩展程序应该让用户感觉灵活轻巧。设计您的应用扩展程序以快速启动,目标是在一秒钟之内。系统终止启动太慢的扩展。

运行应用扩展程序的内存限制明显低于前台应用程序的内存限制。在这两个平台上,系统可能会积极地终止扩展,因为用户希望在Host App中返回其主要目标。某些扩展可能具有比其他扩展更低的内存限制:例如,窗口小部件必须特别有效,因为用户可能同时打开多个窗口小部件。

您的应用扩展程序不拥有主运行循环,因此在主运行循环中遵循既定规则以获得良好行为至关重要。例如,如果您的扩展程序阻止主运行循环,则可能会在另一个扩展程序或应用程序中创建错误的用户体验。

请记住,GPU是系统中的共享资源。应用扩展不会成为共享资源的首要任务; 例如,运行图形密集型游戏的Today小部件可能会给用户带来糟糕的体验。由于内存压力,系统可能会终止此类扩展。大量使用系统资源的功能适用于应用程序,而不适用于应用程序扩展。

设计简化的UI

大多数扩展点要求您至少提供一些用户在打开应用扩展程序时看到的自定义用户界面。扩展的UI应该简单,有限,并且专注于促进单个任务。要提高性能和用户体验,请避免包含不支持扩展主要任务的无关UI。

大多数Xcode应用程序扩展模板都提供了一个可以用来开始的占位符UI。

用户通过其图标及其名称来标识您的应用扩展程序。扩展程序的图标必须与其包含应用程序的应用程序图标相同。使用包含应用程序的图标可以帮助用户确信扩展程序实际上是由他们安装的应用程序提供的。

在iOS中,自定义Action扩展使用其包含应用程序图标的模板图像版本,您必须提供该图标。

iOS共享扩展程序会自动使用包含应用程序的图标。如果您在共享扩展目标中提供单独的图标,Xcode会忽略它。对于所有其他应用扩展程序类型,您必须提供与包含应用程序图标匹配的图标。

有关如何向应用扩展添加图标的信息,请参阅创建资产目录和添加应用图标集或启动图像集。有关iOS应用扩展的图标要求的更多信息,请参阅iOS人机界面指南中的 “App Extensions”

应用扩展程序需要一个简短的,可识别的名称,其中包含包含应用程序的名称,使用模式<包含应用程序名称> - <应用程序扩展名称>。这使用户可以更轻松地管理整个系统的扩展。您可以选择使用包含应用程序的名称作为扩展程序的原样,通常情况下,您的包含应用程序只提供一个扩展名。

应用扩展程序的显示名称由扩展程序目标的CFBundleDisplayName值提供,您可以在扩展程序的Info.plist文件中对其进行编辑。如果您没有为CFBundleDisplayName密钥提供值,则您的扩展程序会使用其包含的应用程序的名称,因为它显示在CFBundleName值中。

提供本地化的应用扩展程序时,请确保本地化应用扩展程序的名称。

某些应用扩展程序也需要简短描述。例如,OS X小部件显示描述以帮助用户在“今日”视图中选择他们想要查看的小部件。要提供此文本,请widget.description在窗口小部件的InfoPlist.strings文件中编辑键的值。

确保您的iOS App扩展适用于所有设备

您必须确保提交的应用扩展程序是通用的:它必须适用于iPhone,iPod touch和iPad。无论您为包含的应用选择哪个目标设备系列,此要求均适用。Xcode中的应用程序扩展模板已针对通用目标设备系列进行了正确配置。

要声明您的应用扩展程序是通用的,请使用Xcode中的目标设备系列构建设置,指定“iPhone / iPad”值。

确保您的应用扩展程序具有通用性

  1. 在键盘项目的Xcode项目导航器中,选择项目文件。

    如果项目编辑器中的项目和目标列表被隐藏,请显示它。为此,请单击项目编辑器选项卡栏左侧的按钮。

  2. 在项目和目标列表中的目标组中,选择应用扩展程序的目标。

  3. 在项目编辑器中选择Build Settings选项卡。

    确保选中“基本”和“组合”按钮,以便于您更轻松地找到所需的设置。

  4. 在项目编辑器的“部署”组中,查看“目标设备系列”设置。对于Debug和Release配置,值应为“iPhone / iPad”。

    如果您找到不同的值,请将其更正为“iPhone / iPad”。

在设计和构建应用扩展时 使用自动布局和大小类。测试您的应用扩展程序,以确保其行为符合您对所有设备大小和方向的预期。如“ 模拟器用户指南”中所述,在iOS模拟器中执行此操作,如果可能,还可以在两个方向上对物理设备进行测试。

请记住,即使您的包含应用仅针对iPad设备系列,您所包含的应用扩展程序也会显示在以兼容模式运行的iPhone应用中。

重要

要通过App Review,您必须指定“iPhone / iPad”(有时称为通用)作为应用扩展程序的目标设备系列,无论您为包含的应用选择哪个目标设备系列。

在未来的iOS更新中,应用扩展程序仅在扩展程序包含应用程序本机支持的设备(或设备兼容模式)上运行。例如,在兼容模式下使用iPhone应用程序时,在仅包含iPad的应用程序中提供的扩展程序将不可见。为确保获得最佳用户体验,我们建议您使用包含的应用,其应用扩展程序是通用的。

调试,配置和测试您的应用程序扩展

注意

您必须对包含应用及其包含的应用扩展程序的代码进行编码

Xcode项目中的所有目标都必须以相同的方式进行代码签名。例如,在测试期间,您可以使用临时代码签名或使用开发人员证书,但必须对项目中的所有目标使用相同的方法。要提交到App Store,请使用您的分发证书来获取所有目标。

使用Xcode调试应用程序扩展非​​常类似于使用Xcode调试任何其他进程,但有一个重要区别:在扩展方案的运行阶段,您将Host App指定为可执行文件。在通过指定主机的UI访问扩展时,Xcode调试器附加到扩展。

Xcode应用程序扩展模板中的方案使用可执行文件的Ask On Launch选项。使用此选项,每次构建和运行项目时,系统都会提示您选择Host App。如果您想要指定每次使用的特定主机,请打开方案编辑器并使用“信息”选项卡进行应用程序扩展方案的“运行”阶段。

将Xcode调试器附加到您的应用扩展程序的步骤如下:

  1. 通过选择“产品”>“方案”> MyExtensionName或单击Xco​​de工具栏中的方案弹出菜单并选择,启用应用程序扩展的方案MyExtensionName

  2. 单击“生成并运行”按钮,告诉Xcode启动指定的Host App。

    Debug导航器指示它正在等待您调用应用程序扩展。

  3. 通过Host App的UI调用应用程序扩展。

    Xcode调试器附加到扩展的进程,设置活动断点,并允许扩展执行。此时,您可以使用与调试其他进程相同的Xcode调试功能。

注意

在构建和运行应用程序扩展项目之前,请确保选择了扩展程序。

如果您使用包含应用程序方案构建和运行,Xcode不会附加到您的应用程序扩展,除非您从包含应用程序调用它,这是一种不寻常的情况,可能不是您想要的。

如果您从与方案中指定的Host App不同的Host App访问您的应用程序扩展,则Xcode调试程序不会附加到扩展程序。

在OS X中,您需要执行启用应用程序扩展的用户步骤,然后才能从Host App访问它以进行测试和调试。您可以使用“系统偏好设置”的“扩展”窗格启用大多数扩展类型。您还可以通过在“共享”或“操作”菜单中选择“更多”来打开“扩展”窗格。

对于OS X Today小部件,使用Widget Simulator来测试和调试它。(在“系统偏好设置”中无法单独执行以启用窗口小部件。)

对于iOS中的自定义键盘,请使用“设置”启用应用程序扩展(“设置”>“常规”>“键盘”>“键盘”)。

Xcode在OS X上的调试会话期间注册构建的应用程序扩展。这意味着如果要在OS X上安装扩展的开发版本,则需要使用Finder将其从构建位置复制到某个位置例如Applications文件夹。

注意

在Xcode调试控制台日志中,应用程序扩展的二进制文件可能与CFBundleIdentifier属性的值相关联,而不是与属性的值相关联CFBundleDisplayName

由于应用扩展必须具有响应性和高效性,因此在运行扩展时,最好在调试导航器中查看调试指标。调试指示器显示扩展在运行时如何使用CPU,内存和其他系统资源。如果您看到性能问题的证据,例如CPU使用率出现异常高峰,您可以使用Instruments来分析您的扩展,并确定需要改进的地方。通过在任何调试仪表报告中单击仪器中的配置文件,您可以在调试会话期间打开仪器(要查看调试仪报告,请单击调试区域中的仪表)。要了解有关调试量规的更多信息,请参阅调试应用程序; 要了解如何使用仪器,请参阅仪器用户指南

注意

在Xcode中选择产品>配置文件可直接在Instruments中构建和运行应用程序扩展。Instruments使用方案的Profile部分中的可执行文件集作为扩展的主机。

要使用Xcode测试框架(即XCTest API)测试应用程序扩展,请编写使用包含应用程序作为主机环境来执行扩展代码的测试。要了解更多有关测试,请参阅测试和Xcode

分发Containing App

您无法向App Store提交应用扩展程序,除非它位于包含的应用程序中,并且您无法将扩展程序从一个应用程序转移到另一个应用程序。

要提供iOS应用扩展程序,您必须向App Store提交包含应用程序。

要提供OS X应用程序扩展,建议您将包含的应用程序提交到App Store,但这不是必需的。

注意

如果您在Mac App Store之外分发OS X应用程序扩展,Gatekeeper会阻止扩展程序运行,直到用户打开并批准包含该应用程序。此外,如果使用除开发者ID之外的证书对签名进行编码,则用户必须明确覆盖Gatekeeper以打开包含的应用程序以使您的扩展可用。

要通过应用审核,您的应用应用必须为用户提供功能; 它不能只包含应用扩展程序。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容