转载

SiriKit实践 - AppExtension介绍

之前把SiriKit的文档啃完了,然后找了很久也没找到完成度比较高的Demo。之前手头上比较忙就先搁置了,最近有时间可以继续了。索性自己摸石头过河,一步步试着实现。

要说SiriKit当然要先了解App Extension了,本篇先介绍一下App Extension。

App Extension

App Extension 顾名思义其是对App的扩展,自iOS8开始新增的特性。之前常见有 Today(Widget)Custom KeyboardShare ,iOS9和10之后陆续又增加了不少,如最近比较热的 iMessageStickerContent BlockerCall Directory 以及本次要分享的 SiriKit

SiriKit实践 - AppExtension介绍

特点与区别

App Extension

App Extension 在工程中以一个target存在,有自己的 info.plist ,有自己的配置项,也有自己的 bundle id (如:主App的为 com.company.xAppName ,那么 AppExtension 通常为 com.company.xAppName.xExtensionName )。它的bundle也是独立的,bundle后缀为 .appex

Containing App

我们的主App就是但是 Containing App 了,实际上 App Extension 并不是一个独立的App,它不能独立安装与卸载,他是随着主App的安装而安装、卸载而卸载的。而且提交AppStore的时候主App必须要实现一些功能。

Host App

调用Extions的App就是 Host App ,比如 Intent ExtensionHost AppSiri

App Extension 是与 Host App 进行通讯, App ExtensionContaining App 通过 openUrl: 进行通讯,而 Host AppContaining App 之间就没有任何关系了,大致关系如下图:

SiriKit实践 - AppExtension介绍

生命周期

它的生命周期与主App也不同, App Extension 是随着用户触发了而创建和启动,用户取消操作或者离开后一段时间他会被系统自动杀死。

SiriKit实践 - AppExtension介绍

数据与代码共享

毕竟 App ExtensionContaining App 并不是一体的,所以数据和代码上的共享是有些需要注意的。

数据共享

开启App Group

首先你需要给需要数据共享的target开启App Group并设置Group Id(只有开发者账号可以进行), 注意共享数据的target的group id要勾选一样的。

如下图,我的主App target和Intent Extension的Target开启并设置了GroupId(没有group id需要先点+号增加一个)

SiriKit实践 - AppExtension介绍

SiriKit实践 - AppExtension介绍

NSUserDefaults方式共享

使用 NSUserDefaults 的初始化方法 initWithSuiteName: 来获取共享的 NSUserDefaults 对象,再进行操作

NSString       *groupId     = @"你取的App Group的Id";
NSUserDefaults *userDefault = [[NSUserDefaults alloc] initWithSuiteName: groupId];
//然后正常的取值和赋值就行了
[userDefault setValue:@"value" forKey:@"key" ];
[userDefault valueForKey:@"key"];

NSFileManager方式共享

使用 NSFileManager 对象的 containerURLForSecurityApplicationGroupIdentifier: 方法,然后获取共享目录路径,再进行操作,如:

NSString *groupId   = @"你取的App Group的Id";
NSString *groupPath = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier: groupId].path;

NSLog(@"groupPath: %@", groupPath);
//然后用writeToFile、某个类的WithContentsOfFile之类的操作进行读写就行了

使用数据库

使用SQLite、CoreData等数据库进行共享,但是数据库文件还是得靠 NSFileManager 来读取

主App与Extension各种路径

在主App和Extension中分别打印groupPath、bundlePath和sandyPath,可以发现,它们的groupPath是一样的,bunldePath和sandyPath都不同

//---主App打印
groupPath: /private/var/mobile/Containers/Shared/AppGroup/4616FF64-1879-4A12-BCC4-C2E7F82C612A 

bundlePath: /var/containers/Bundle/Application/ED47E5E2-F867-4179-AF99-0609F98CA4DA/SiriKitTest.app 

sandyPath: /var/mobile/Containers/Data/Application/A79D26BD-B003-4BDB-B3C8-3B73FA7AB08B

//---Extension打印
groupPath: /private/var/mobile/Containers/Shared/AppGroup/4616FF64-1879-4A12-BCC4-C2E7F82C612A 

bundlePath: /private/var/containers/Bundle/Application/03D71C80-B9C0-4480-82A7-044D129614F3/SiriKitTest.app/PlugIns/SendMessageIntentUI.appex 

sandyPath: /var/mobile/Containers/Data/PluginKitPlugin/E241732D-5383-416C-A411-222B8C780E2B

代码和图片资源共享

使用Framework

将两边都会用到的代码,打成Framework,然后引入

使用CocoaPods

制作私有CocoaPods库,进行引入。Podfile注意给Intent或者IntentUI的target也加上需要的。如:

SiriKit实践 - AppExtension介绍

勾选target membership

对已有的一些要共用的类在右侧勾选,新建类的时候也考虑是否要勾选。

SiriKit实践 - AppExtension介绍 SiriKit实践 - AppExtension介绍

原文  http://www.devhy.com/2016/12/10/21-sirikit-practice-1/
正文到此结束
Loading...