在这里放出原文链接地址
Part 5.1: 创建一个 Intents UI Extension
当你处理一个 Intent
时, Siri
和 Maps
通常会使用一个默认的 UI 界面将 Intents Extension
返回的响应者对象( response object ) 中的详细内容展示给用户, 如果你希望在此基础上添加你自定义的 UI 界面, 此时你需要添加一个 Intents UI Extension
.
Intents UI Extension
不会替代你用来处理 Intent
对象的 Intents Extension
. 它是一个单独的 App 扩展, 使用它来自定义你的 UI 界面, 向用户展示响应者对象( response object ) 中的内容. 你可以在它上面添加你 App 的标识, 也可以在它上面添加一些附加的信息, 如此一来, 你可以给用户一种很熟悉的感觉.
当你支持一下场景( domains ) 时, 你可以提供 Intents UI Extension
:
- 消息 ( Messaging )
- 支付 ( Payments )
- 旅行预订 ( Ride booking )
- 健身 ( Workouts )
Intents UI Extension
中最主要的一个对象是一个 View Controller
, 使用它来自定义你向用户所展示的内容. 一个Intents UI Extension
中只有一个 View Controller
, 所以它必须有能力显示所有你所支持场景( domains ) 的内容. 当然, 你也可以为你每一个支持的场景 ( domains ) 分别创建一个 Intents UI Extension
.
Part 5.2: 配置你的 Xcode 工程
当你创建一个 Intents Extension
时, 你可以同时创建一个 Intents UI Extension
, 当然, 只要你有需要, 你在任何时间单独添加 Intents UI Extension
也是没问题的.
在项目中添加一个新的 Intents UI Extension
:
使用 Xcode 打开你的工程.
-
选择 File -> New -> Target
-
在 iOS 标签下选择
Intents UI Extension
, 点击 Next.
指定文件名称、开发语言以及其他的选项. 点击 Finish.
Xcode 提供的模板包含了一个 Storyboard
文件, 其中包含了一个初始的视图控制器, Siri
和 Maps
会通过 Storyboard
中的初始视图控制器来向用户显示你的自定义内容, 所以先将初始视图控制器的内容初始化成你想要展示的默认内容. 你也可以在 Storyboard
文件中添加新的视图控制器, 将新添加的视图控制器作为初始视图控制器的子视图控制器来使用. 所以为了你自定义 UI 可以正确的显示你想要的内容, 你有责任去管理初始视图控制器和新建视图控制器之间的所有交互过程.
Intents UI Extension
中的 Info.plist
文件将会向SiriKit
提供一些信息, 你的Intents UI Extension
都支持哪些 Intents
就是在这个文件中配置的. 下面表格中展示的3个 Key, 是你必须在Info.plist
中包含的. 另外需要注意的是 NSExtensionAttributes
这个 Key, 你需要在这个 Key 中详细说明你的 Intents UI Extension
都支持哪些场景.
Key | 描述 |
---|---|
NSExtensionAttributes | 该 Key 对应的值是一个字典, 该字典中必须包含 IntentsSupported Key, 该 Key 对应的值是一个字符串数组. 这些字符串的值实际就是你所支持的 Intent 的类名. 配置这个 Key 就跟配置 Intents extension 时一样. |
NSExtensionMainStoryboard | 该 Key 对应的值就是你显示自定义内容的 Storyboard 名称. 如果你不想使用 Storyboard 而是使用代码来初始化你的视图控制器, 你可以使用NSExtensionPrincipalClass 这个 Key 来替换NSExtensionMainStoryboard . |
NSExtensionPointIdentifier | 该 Key 的内容必须为 com.apple.intents-ui-service.
|
指定 Intents UI Extension
所支持的 Intent
:
选择你的
Info.plist
文件.-
展开
NSExtension
和NSExtensionAttributes
这两个 Key.
在
IntentsSupported
Key 中添加你需要支持的Intent
, 字符串类型, 值则是Intent
的类名.
了解更多配置 Info.plist
的内容, 请查看: Information Property List Key Reference
Part 5.3: 实现你的视图控制器
Storyboard
中的初始视图控制器, 就是用来向用户展示自定义内容的. 在向用户展示你的自定义 UI 界面之前, Siri
和 Maps
将会先加载初始视图控制器, 并且调用其中的 configureWithInteraction:context:completion: 方法, 实现这个方法时, 使用该方法提供的交互对象( interaction object ) 来配置你视图控制器中需要显示的内容. context
参数将会告诉你视图控制器应该显示 Siri
或 Maps
的内容, 所以此时你是有机会通过这个参数来判断你应该向用户展示哪些自定义内容的.
在用户 dismiss
掉 Siri
或Maps
之前, 你的视图控制器都是显示在屏幕中的, 你可以使用 Timer
或其他的一些技术来更新你的界面. 该视图控制器同样遵守普通视图控制器的生命周期, 例如显示、隐藏之类的, 不同的是, 该视图控制器是不接收任何触摸事件的, 而且你也不可以在上面添加任何手势. 所以在该控制器上不要创建任何需要用户交互的试图.
下图中展示的是 Intents UI Extension
和 它的视图控制器的生命周期. 系统创建视图控制器, 并且调用configureWithInteraction:context:completion: , 并且该方法会传入一个交互对象 ( interaction object ), 用这个对象来配置你的界面. 一旦配置完成, 你的视图控制器将会显示在屏幕中, 当你的视图控制器出现在屏幕上以后, 你可以做一些动画之类的操作, 也可以使用 Timer
或其他的一些技术来实现你界面的更新逻辑, 但是请记住, 它是不接受任何事件的.
注意:
当视图控制器出现在屏幕上以后,Maps
将会再一次调用configureWithInteraction:context:completion: 方法将需要更新的信息发送给你, 让你来显示最新的内容. 例如:Maps
将会调用这个方法, 将旅行预订的最新状态发送给你, 利用这个时机来更新你的界面.
当用户 dismiss
掉 Siri
或 Maps
以后, 系统将会 release
掉对视图控制器和 Intents UI extension
的引用. 你的视图控制器仅仅用来展示信息就可以了, 当视图控制器从屏幕中消失的时候, 不要试图保存任何数据 或 和你的 App 产生任何的联系.
对于如何实现 Intents UI extension
中的视图控制器, 这里给出几条建议:
-
在视图控制器中添加你App的标识: 使用你 App 的主色调、图片、图标, 以及其他的一些设计元素来提升用户对你
Intents UI extension
的熟悉感是一个不错的选择. -
通过初试视图控制器的子视图控制器来切换你要显示的内容:
Intents UI extension
中仅包含了一个主视图控制器(初试视图控制器), 所以当你希望根据不同的Intent
来显示不同的内容时, 你可以使用子视图控制器来管理不同Intent
所对应的不同内容. 在configureWithInteraction:context:completion: 方法中, 根据不同的Intent
对象初始化不同的视图控制器. -
只有当你视图控制器完全显示, 你才可以做一些动画操作: 等到视图控制器声明周期到达
viewDidAppear:
之后, 再提交你的动画. 停止动画则需要在viewWillDisappear:
方法中. - 尽可能快的配置视图控制器的 View: 由于你的视图控制器在屏幕中显示的时间不会很长, 所以尽可能使用一些本地的数据和configureWithInteraction:context:completion: 方法中提供的交互对象( interaction object ) 来配置你的视图. 如果你需要从服务器上获取一些数据来进行显示, 此时你应该异步的进行数据请求, 当请求成功后再来刷新你的页面.
- 不要在你的界面中添加广告: 你可以添加一些和用户相关的信息, 但是广告这东西是被禁止的.
-
当你希望隐藏掉你的自定义界面时, 返回一个 CGSizeZero 就可以了: 当你的视图控制器没有任何附加信息需要展示给用户时, 你可能需要隐藏掉你的视图控制器, 此时你可以在 configureWithInteraction:context:completion: 方法中回调
completion block
时传入一个CGSizeZero
就可以了.
了解更多关于配置视图控制器的内容, 请查看: INUIHostedViewControlling Protocol Reference
Part 5.4: 替换默认的界面
对于一个旅行预订( Ride booking ) 或消息( Messaging ) 相关的 App 来说, 如果系统提供的默认 UI 和你提供的 UI 产生了冲突, 那么此时你可以将系统提供的 UI 隐藏掉. 对于消息( Messaging ) App 来说, Siri
默认会展示消息的内容和消息接收者. 对于旅行预订( Ride booking ) App 来说, Siri
和 Maps
将会展示一个地图来显示用户的位置. 如果你想用你的自定义界面来显示相同的信息, 使用 INUIHostedViewSiriProviding 协议来禁止系统提供默认界面的显示.
了解更多禁止默认页面显示的内容, 请查看: INUIHostedViewSiriProviding Protocol Reference
Lemon龙说:
如果您在文章中看到了错误 或 误导大家的地方, 请您帮我指出, 我会尽快更改
如果您有什么疑问或者不懂的地方, 请留言给我, 我会尽快回复您
如果您觉得本文对您有所帮助, 您的喜欢是对我最大的鼓励
如果您有好的文章, 可以投稿给我, 让更多的 iOS Developer 在简书这个平台能够更快速的成长