一同养成写作习气!这是我参加「日新计划 4 月更文应战」的第30天,点击查看活动详情。

前语

扩展 (Extension) 是 iOS 8 和 OSX 10.10 参加的一个非常大的功用点,开发者能够经过体系供给给咱们的扩展接入点 (Extension point) 来为体系特定的服务供给某些附加的功用。

运用场景:

  1. 聚合收款app根据extension拦截消息推送完结 app处于后台/被杀死的状况仍可进行收款到账的言语播报:blog.csdn.net/z929118967/…
  2. 经过其他app如Safari、WeChat、相册app同享文本、链接、文件到咱们自己开发的App, 完结文件的上传和信息同享;常用于咱们从其他app上传简历到招聘app。

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

增加扩展的详细完结过程:File->New->Target, Application Extension->xxxx Extension

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)
iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)
iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

I App Extension

1.1 App Extension类型

关于 iOS 来说,能够运用的扩展接入点有以下几个:

  • NotificationServiceExtension

iOS NotificationServiceExtension完结VoiceBroadcast【app处于后台/被杀死的状况仍可进行言语播报】iOS12.1以上在后台或许被杀死无法语音播报的解决方案

———————————————— 版权声明:本文为CSDN博主「#大众号:iOS逆向」的原创文章,遵从CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

  • Today 扩展 – 在下拉的告诉中心的 “今日” 的面板中增加一个 widget

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

  • 同享扩展 : 运用户在不同的运用程序之间同享内容。点击同享按钮后将网站、文件或许相片经过运用同享。

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

  • 动作扩展 – 点击 Action 按钮后经过判别上下文来将内容发送到运用:动作扩展允许在Action Sheet中创立自界说动作按钮,例如允许用户为文档增加水印、向提示事项中增加内容、将文本翻译成其他言语等。动作扩展和同享扩展相同都能够在恣意的运用程序中激活运用,相同也需求开发者进行相应的设置

  • 相片修改扩展 – 在体系的相片运用中供给相片修改的才能:将你供给的滤镜或修改东西嵌入到体系的相片和相机运用程序中,这样用户就能够很容易地将其运用到图画和视频中

  • 文档供给扩展 – 供给和办理文件内容:假如你的运用程序是给用户供给iOS文档的长途存储,就能够创立一个Document Provider,让用户能够直接在任何兼容的运用程序中上传和下载文档

  • 自界说键盘

供给一个能够用在所有运用的替代体系键盘的自界说键盘或输入法:自界说键盘需求用户在设置中进行装备,才能在输入文字时运用。

比如: iOS上USB Keyboard装置后,翻开“设置 – 通用 – 键盘 – 键盘 – 增加新键盘“,在”第三方键盘“区域点击”USB Keyboard“。

  • Audio

经过音频单元扩展,你能够供给音频效果、声响生成器和乐器,这些能够由音频单元宿主运用程序运用,并经过运用程序商铺分发。

1.2 扩展的生命周期

运用程序扩展 并不是一个独立的运用程序,它是包括在运用Bundle里一个独立的包,后缀名为.appex。包括运用程序扩展的运用程序被称为容器运用(Containing App),能够运用该扩展的运用被称为宿主运用(Host App)

  • 比如:,Safari里运用微信的扩展,将一个网页同享到微信中,则Safari就是宿主运用,微信就是容器运用。

当用户在手机中装置容器运用时,运用程序扩展也会随之一同被装置;假如容器运用被卸载,运用程序扩展也会被卸载。

宿主运用程序中界说了供给给扩展的上下文环境,并在响运用户恳求时发动扩展。运用程序扩展通常在完结从宿主运用程序接收到的恳求不久后终止。

扩展的生命周期和包括该扩展的容器 app (container app) 本身的生命周期是独立的,精确地说它们是两个独立的进程。

  • 扩展需求对宿主 app (host app,即调用该扩展的 app) 的恳求做出呼应,
  • 当然,经过进行装备和一些手法,咱们能够在扩展中拜访和同享一些容器 app 的资源.
    iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

一般来说,用户在宿主 app 中触发了该扩展后,扩展的生命周期就开始了:

比如在同享选项中挑选了你的扩展,或许向告诉中心中增加了你的 widget 等等。

而所有的扩展都是由 ViewController 进行界说的,在用户决议运用某个扩展时,其对应的 ViewController 就会被加载,因而你能够像在编写传统 app 的 ViewController 那样获取到比如 viewDidLoad 这样的办法,并进行界面构建及做相应的逻辑。

扩展应该坚持功用的单一专注,并且迅速处理使命,在履行完结必要的使命,或许是在后台预约完结使命后,一般需求赶快经过回调将控制权交回给宿主 app,至此生命周期完毕

  • 关于运用程序扩展的生命周期,咱们可简单描绘如下 1)用户挑选需求运用的运用程序扩展。 2)体系发动运用程序扩展。 3)运行运用程序扩展的代码。 4)体系终止运用程序扩展的运行。

II App Extension通讯

运用程序扩展、容器运用和宿主运用之间是如何通讯?

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)
在宿主运用中翻开一个运用程序扩展,宿主运用向运用程序扩展发送一个恳求,即传递一些数据给运用程序扩展,运用程序扩展接收到数据后,展示运用程序扩展的界面并履行一些使命,当运用程序扩展使命完结后,将数据处理的成果回来给宿主运用。

  • 虚线部分表明运用程序扩展与容器运用之间存在有限的交互办法

体系Today视图中的小组件,能够经过调用NSExtensionContext的-openURL:completionHandler:办法使体系翻开容器运用,但这个办法只限Today视图中的小组件。

关于任何运用程序扩展和它的容器运用,有一个私有的同享资源,它们都能够拜访其中的文件。

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

2.1 扩展和容器运用的交互

  1. 经过App Group Identifier创立一个NSUserDefaults类的实例目标,存储键值对类型的数据 经过NSFileManager类的-containerURLForSecurityApplicationGroupIdentifier:办法获取同享资源的文件途径,然后读写相应文件。

经过开启 App Groups 和进行相应的装备来开启在两个进程间的数据同享(选中Capabilities,翻开App Groups选项)。

这包括了运用 NSUserDefaults 进行小数据的同享,或许运用 NSFileCoordinator 和 NSFilePresenter 乃至是 CoreData 和 SQLite 来进行更大的文件或许是更复杂的数据交互。(增加VPN装备,Packet Tunnel Provider extension :能够运用这个扩展点来完结客户端的自界说VPN地道协议。

  1. 自界说的 url scheme 也是从扩展向运用反馈数据和交互的途径之一(点击跳转到APP

  2. 能够运用 iOS 8 新引入的克己 framework 的办法来安排需求重用的代码,这样在链接 framework 后 app 和扩展就都能运用相同的代码了

2.2 进程间的实时通讯方案: local socket(解决扩展和容器运用的实时通讯问题)

blog.csdn.net/z929118967/…

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

III App Extension示例

  • iOS NotificationServiceExtension完结VoiceBroadcast【app处于后台/被杀死的状况仍可进行言语播报】iOS12.1以上在后台或许被杀死无法语音播报的解决方案

  • 增加VPN装备 (Packet Tunnel Provider extension ) :能够运用这个扩展点来完结客户端的自界说VPN地道协议。

  • 比如: iOS上USB Keyboard装置后,翻开“设置 – 通用 – 键盘 – 键盘 – 增加新键盘“,在”第三方键盘“区域点击”USB Keyboard“。

3.1 iOS NotificationServiceExtension完结VoiceBroadcast

  • NotificationServiceExtension

iOS NotificationServiceExtension完结VoiceBroadcast【app处于后台/被杀死的状况仍可进行言语播报】iOS12.1以上在后台或许被杀死无法语音播报的解决方案

———————————————— 版权声明:本文为CSDN博主「#大众号:iOS逆向」的原创文章,遵从CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

3.2 Today

TodayViewController中的代码和普通运用程序中新建的视图控制器的代码基本上是相同的,仅仅多完结了NCWidgetProviding协议。在NCWidgetProviding协议中,有一个-widgetPerformUpdateWithCompletionHandler:办法,

咱们能够在这个办法中更新小组件里的内容并重新烘托界面,当小组件完结内容更新后,需求调用相应的block,给体系回来合适的更新成果。

要完结的TodayDemo小组件功用比较简单,不需求处理界面更新的相关逻辑。

  • 同享数据

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)

    NSURL *url = [[NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:kGroupIdentifier] URLByAppendingPathComponent:@"TodayResult.txt"];
    int result = [[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil] intValue];
    self.numLabel.text = [NSString stringWithFormat:@"%d", result];

3.3 同享数据(经过开启 App Groups 和进行相应的装备来开启在两个进程间的数据同享)

iOS 小技能:App Extension (App Extension类型、生命周期、App Extension通信、App Extension示例)
在运用程序扩展里同享数据一般有如下两种办法

在运用程序扩展里同享数据一般有如下两种办法。
经过App Group Identifier创立一个NSUserDefaults类的实例目标,存储键值对类型的数据
经过NSFileManager类的-containerURLForSecurityApplicationGroupIdentifier:办法获取同享资源的文件途径,然后读写相应文件。
    NSURL *url = [[NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:kGroupIdentifier] URLByAppendingPathComponent:@"TodayResult.txt"];
    int result = [[NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil] intValue];
    self.numLabel.text = [NSString stringWithFormat:@"%d", result];
- (void)saveToUserDefaultsWithString:(NSString *)string {
    NSUserDefaults *userDefaults = [[NSUserDefaults alloc] initWithSuiteName:kGroupIdentifier];
    [userDefaults setObject:string forKey:kTodayDemoResult];
}
- (void)saveToFileWithString:(NSString *)string {
    NSURL *url = [[NSFileManager.defaultManager containerURLForSecurityApplicationGroupIdentifier:kGroupIdentifier] URLByAppendingPathComponent:@"TodayResult.txt"];
    [string writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:nil];
}