大多数浏览器和
Developer App 均支持流媒体播放。
-
探索 App Intents 的增强功能
使用 App Intents 让你的小部件生动活泼!探索最新更新并了解如何利用动态选项和用户交互性为你的 App 快捷指令构建更好的体验。我们将分享如何与 Apple Pay 集成、更有效地构建代码以及将快捷指令 App 集成提升到新的水平。 有关 App Intents 和 App 快捷指令的更多信息,请观看 WWDC23 的“使用 App 快捷指令聚焦你的 App ”。
资源
相关视频
WWDC23
-
下载
♪ ♪
Roman Efimov:大家好 我叫 Roman Efimov 是一名 Shortcuts 团队的工程师 今天 我将给大家介绍 App Intents 的一些新功能和改进 帮你创建更好的 App 让我们从小组件开始 如你所知 小组件已经日渐成为 iOS 用户体验 的重要部分 现在 App Intents 和小组件无缝协作 通过交互性和配置 为用户提供新体验 接下来 我会继续介绍我们今年在开发者体验 方面的改进 我会介绍一些 框架支持等质量方面的提高 以及最近在静态提取方面的改善 最后再深入讲解一下 快捷指令 App 和 App Intents 集成的更新 议程很紧凑 所以我们先从几个 令人兴奋的小组件更新说起 先来谈谈小组件配置 当你创建一个可配置的小组件时 你可以指定你希望用户 在小组件的背面能够选择的选项 这些选项被称为参数 您可以使用与在 App 中 添加 Siri 和快捷指令支持时 相同的系统来定义这些参数:Intents 小组件的配置 UI 展示了一个 包含在相应意图里的 参数的有序列表 添加到意图中的每个参数 都会以行的形式 显示在小组件的配置界面 过去 你得使用一个意图定义文件 在 Xcode 中定义你的意图 现在在 iOS 17 中 我们让这件事变得更简单 你可以直接在你的小组件扩展代码中 使用 App Intents 来定义你小组件配置的架构
要做到这一点 你首先要开始使用 AppIntentConfiguration WidgetConfiguration 类型 而不是你可能之前用于 配置你小组件的 IntentConfiguration 接下来再定义一个新类型 使其符合 WidgetConfigurationIntent 协议 WidgetConfigurationIntent 是 App Intent 的子协议 并且你可以直接在小组件扩展代码中 使你的类型符合这个协议 我一直在开发我的 Bus Schedule App 的小组件 它可以显示特定站点下一班车 的到达时间和路线 这样用户不需要打开 App 就可以快速查看 下一班车的到达时间 我会使用 App Intents 为我的小组件提供配置意图 为了让用户配置我的 Next Bus 小组件 我会先从定义一个符合 WidgetConfigurationIntent 协议 的结构开始 这个结构还包括以下参数: 一个公交车站 可以从已保存的站点 列表中选择或者搜索一个新站点; 特定的公交路线; 以及所选路线的行驶方向 定义完配置我的小组件 所需的参数后 我需要为每一种参数类型 提供动态选项 以前 给参数提供动态选项 需要创建一个单独的意图扩展 有了 App Intents 我可以直接在小组件扩展中 实现查询和动态选项提供者 从而使项目更简洁、更高效 如果你想了解更多 动态选项提供者和查询的相关信息 我推荐你观看视频 “对 App Intents 的深度解析” 现在 我们再来谈谈把 SiriKit 的 现有小组件迁移到 App Intents 的相关问题 把你现有的小组件配置 迁移到 App Intents 很简单 事实上 只需要在 Xcode 里 点击一下就可以完成 迁移小组件可以让你同时支持 最新 OS 版本 和不能迁移小组件 到 App Intents 的既往版本 现有配置小组件可以继续运行 如果你不再需要 支持以前的 OS 版本了 删除 SiriKit 意图定义文件即可 要完成迁移 在你的意图定义文件中 找到 SiriKit 小组件配置意图 并且点击 Convert to App Intent 按钮 Xcode 会生成等同于旧意图定义的 App Intents 代码 你需要确保架构保持不变 这代表 所有 App Intent 参数的名称和类型 都要和你的意图定义中的一致 你可以在 App Intent 中添加新参数 你可以添加一个可选参数 甚至一个带有默认值的必选参数 添加参数前创建的现有小组件 会赋予参数一个空值 或者你已经定义过的默认值 如果你确实打算 支持先前 iOS 版本的用户 并让他们使用这个新参数 你就需要保留 你的 SiriKit 意图定义文件 同时把这个新参数添加进去 用户更新 App 的时候 小组件也会跟着自动迁移 测试迁移是否顺利至关重要 因为你的 App 只有一次机会 如果你想了解更多关于迁移的信息 我推荐你观看视频 “把自定义意图 迁移到 App Intents” 我们再来说小组件的交互性 用户轻点和切换按钮时 小组件也会作出反应 让用户可以 直接在主屏幕上调整设置 播放媒体文件 或者启用 App 的任何 其他重要功能 在我的 Next Bus 小组件里 我想把时间按钮设置为可轻点 用户轻点按钮以后 App 就会设置一个提醒 保证他们知道何时出发 这样他们就不会错过公交车了! 怎么实现呢? 更新后的 SwiftUI Button 和 Toggle 已经支持 App Intent 这让增加小组件的交互性变得简单 如果你以前使用过 App Intent 你应该可以立即上手 首先 我需要定义一个符合 App Intent 协议的结构 然后用 Parameter 属性包装器 注释任何关键属性 以向系统反馈我需要相关信息 来执行这个操作 之后 我要实现一个能真正执行操作 的 perform 方法 最后 在小组件视图中 把 SetAlarm App Intent 和按钮联系在一起即可 SwiftUI 和 App Intents 的集成 不仅适用于交互式组件 也适用于常规 SwiftUI App 通过把代码合并到 App Intents 你可以精简操作并确保 整个 App 的行为一致 由于 App Intents 既可以用作配置 也可以用作交互性动作的提供者 把 Intent 代码再使用到快捷指令上 就变得非常简单 举个例子 我的 ShowNextBus 小组件配置意图 既可以用作小组件配置 也可以用作快捷指令操作 可以在我需要的时候 给我提供最新信息 此外 我用来增加 小组件交互性的 App Intent 也可以用作很好的快捷指令操作 让用户给自己在等待的公交车 的到达时间设置提醒 如果你想进一步了解更多 小组件交互性的相关信息 请查看视频 “如何让小组件生动活泼” 我们再来看几种 能增强小组件配置功能 改善小组件配置设计的先进技术 先来聊聊动态选项和查询的改善 动态选项是一个界面 给 App Intent 的参数 提供可能的值 而且它可以通过符合 DynamicOptionsProvider 结构 或 EntityQuery 系列协议来实现 在某些情况下 你可能只想显示 在满足某些基于另一个参数值 的特定情况时可用的选项 比如 在我的小组件配置中 我只想显示基于公交车站参数的 可用路线选项 我可以通过用 iOS 17 的新 API IntentParameterDependency 来实现 它是一个属性包装器 让你能在 DynamicOptionsProvider 或查询中访问你的意图参数 你可以读取这些参数并使用它们创建 更多动态和上下文感知的选项 在我的例子中 我返回由用户选择的公交车站 过滤过的可用公交路线 IntentParameterDependency 适用于所有环境 比如小组件、快捷指令和 专注模式过滤器 在我的例子里 我建立了一个符合 EntityQuery 协议的结构 叫作 BusRouteQuery 这个结构有一个属性 叫作 ShowNextBus 由 IntentParameterDependency 属性包装器包装 这就意味着公交车路线查询 依赖于 showNextBus App Intent 特别是依赖公交车站参数 请注意 suggestedEntities 方法 它返回了一个建议的路线对象数组 它首先检查 showNextBus 意图属性是否为 nil 如果不是的话 它会过滤可用路线 让用户只看到与自己选定的 公交车站相匹配的路线 IntentParameterDependency 也能依赖多个参数 比如 在方向查询里 我想同时依靠公交车站和路线参数 来提供方向选项 你也可以在同一个查询 或动态选项提供者中 依靠多个 App Intents 我的方向查询 读取了两个意图的参数: ShowNextBus 和 ShowFavoriteRoute IntentParameterDependency 属性包装器被用来指定 对 ShowNextBus Intent 的 busStop 和 route 参数以及 ShowFavoriteRoute Intent route 参数的依赖关系 路线计算属性返回 showNextBus 或 showFavoriteRoute 的值 返回哪一个取决于哪一个值可用
小组件配置通常有数组参数 比如 我的 Favorite Routes 小组件 可以显示用户最喜欢的路线 的公交车时刻表 可是由于屏幕空间的限制 用户最多只能选三条路线 我该怎么声明这一点呢? 在新的 iOS 17 系统中 你可以在定义 数组参数时声明大小 这里的大小也可以接收 小组件尺寸到数组大小的映射 因为有时较大的小组件 比较小的小组件能容纳更多项目 我定义了 Widget Configuration App Intent 和它的参数后 我就需要确定哪些参数显示给用户 以及什么时候显示 ParameterSummary 规定 App Intent 参数 的视觉表现 它驱动了 App Intent 在快捷指令 编辑器和专注模式过滤器中的外观 现在还要加上小组件配置 你可以使用参数摘要 来定义在什么条件下 显示哪些参数 对于小组件 UI 会首先显示 Summary 句子中的参数 然后再显示闭包中列出的 任何其他参数 这里 这个句子包含了路线参数 闭包包含了 includeWeatherInfo 所以它们以这个顺序 显示在配置 UI 中 在新的 iOS 17 系统中 你可以使用 带有小组件系列的 When 语句 让你的小组件配置 根据小组件的大小而变化 例如 我只想在大尺寸小组件中 显示表现天气信息 的切换按钮 而其他大小的小组件没有这个功能 所以我把 includeWeatherInfo 参数 只添加到了 大尺寸小组件的参数摘要中 而没有为小尺寸小组件添加参数 所以参数隐藏了 现在我已经使用 App Intents 配置了我的小组件 我要怎么确定 用户点击小组件时会发生什么呢? 每当用户轻点小组件的任何地方 他们就会被带到我的 App 我想直接向他们显示 他们在小组件配置中 选择的特定路线的相关信息 当用户点击小组件 并启动了你的 App 时 你可以通过调用用户活跃度的 widgetConfigurationIntent 方法 来得到相关的配置意图 获得 App Intent 后 你就可以 使用它相应地更新你 App 的 UI 这里 我提取了 Configuration Intent 的内容 并使用它把我的 App 定位到了相应站点和路线 的特定公交车站视图 你在创建小组件时 需要确保 用户能在智能叠放中 恰到好处地看到它 为了做到这一点 你需要在 iOS 和 watchOS 上 为小组件建议使用新的 RelevantContext API 我们从以前的 INInteraction、INDailyRoutine 和 INRelevantShortcut API 中汲取了灵感 设计了新的 RelevantIntentManager 和 RelevantIntent 它们更适用于 Swift 和 App Intents 无缝协作 试想一下一个体育 App 想在比赛时显示它的小组件 有了新的 RelevantContext API 你可以指定这个意图 以及它的相关日期范围 通过提供相关日期信息 这个体育 App 小组件就会 在智能叠放中自动推荐 确保用户能在最重要的时候 轻松获取比赛信息
Relevance API 也非常适合 显示你腕表的复杂功能 如果你想进一步了解更多 watchOS 方面的相关信息 请观看视频“在 Apple Watch 上 为智能叠放构建小组件” 我们已经介绍了小组件 下面我们来深入了解一下 我们在 iOS 17 和 Xcode 15 中 对开发者体验做出的改善 让我们从框架支持开始 如果你的 App 需要可以同时在主 App 和 App Intents 扩展中 执行 App Intents 那么你目前需要把你的 App Intent 代码编译到两个目标中 不幸的是 这种方法会导致代码重复 从而产生维护问题 增加错误或不一致的可能性 这种方法 还会增大二进制数据的大小 对 App 性能和用户的下载时间 产生负面影响 在 iOS 17 和 Xcode 15 中 框架可以直接执行 App Intents 所以不需要编译两次代码 你现在可以使用 AppIntentsPackage API 在你的 App 中递归地导入依赖项 让类型 符合 AppIntentsPackage 协议 这样你的 App 和框架都可以 从其他框架重新导出元数据 我会使用框架支持来简化 我的 Bus Schedule App 的构建 我采用了一个 BusScheduleIntents 框架 它为查看公交车时刻表 提供多种 App Intents 它可以在 没有任何依赖项的情况下重新导出 我还采用了一个 BusScheduleUI 框架 它为 Bus Schedule App 提供自定义界面元素 这个框架依赖 BusScheduleIntents 框架并对其进行重新导出 最后 我从我的 Bus Schedule App 导入 BusScheduleUI 框架 AppIntentsPackage 是一个协议 我可以让我的 SwiftUI App 结构体 符合这个协议 Bus Schedule App 只需要注明 它对 BusScheduleUI 框架 的直接依赖 通过执行 ShowSchedule App Intent 我现在可以在 Bus Schedule App 中 创建一个 SwiftUI 按钮 来显示我最喜欢的公交车路线 快捷指令用户也可以使用同样的 App Intent (ShowSchedule) 这就代表他们可以 创建自定义快捷指令 来快速获取他们最喜欢的公交车路线 时刻表而不用打开 App 把你的 App Intents 迁入框架 这能让你的代码库 变得更简单、更精简 使用 App Intents 创建组件时 新的框架支持尤其重要 因为你可能需要同时访问 App 和小组件扩展的相同意图 这里还有一个让你的 App Intents 代码更模块化的技巧: 你现在可以创建一个 AppShortcutsProvider 并在 App Intents 扩展中 定义 App 快捷指令 以前 你必须完全在主 App 软件包 中定义 App 快捷指令 这就意味着 运行 App 快捷指令时 App 总是在后台启动 现在你可以在 App Intents 扩展中 定义你的 App 快捷指令 这有助于提高 App 性能 因为你可以优化 App Intents 扩展 使其比整个主 App 启动得更快 并避开启动 UI、分析器 或其他非关键代码 所有这些功能都依赖 我们在 Xcode 15 中增强的 静态元数据提取功能 所以接下来我们聊聊 代码建立后 如何静态提取 App Intents 内容 Swift 编译器 输出代码中可用类型的相关信息 以及来自 App Intents 实施的 类型层面和值层面的相关信息 然后我们用另一个工具 解析这些信息 在你创建好的代码中生成一个 Metadata.appIntents 目录 包含 描述 App Intents 的文件、参数 实体、查询等等 在 Xcode 15 中 静态提取过程得到了显著改善 变得更快、更可靠 并能适用于更多情况 用 Xcode 15 创建 App 时 如果 Xcode 无法静态提取它想提取的内容 你就会直接在 Xcode 编辑器里 看到出错提示和行数 这样你就知道去哪里修复这个问题 在介绍快捷指令集成前 还有两个 我们今年为 App Intents 添加的 强大功能值得一提 第一种功能是 继续在 App 中执行意图 即使这个意图之前是在后台运行的 我们把它叫作 ForegroundContinuableIntent 协议 举个例子 如果由于无效参数或连接问题 获取下一班公交车的 App Intent 无法检索到公交车时刻表 我可以提示用户 继续在 App 中解决这个问题 要做到这一点 首先要让我的 App Intent 符合 ForegroundContinuableIntent 协议 ForegroundContinuableIntent 协议 是为那些 一开始在后台运行 但是可能需要 在前台继续运行的意图设计的 接下来再调用 needsToContinueInForegroundError 方法 这个方法会返回错误给我 我抛出这个错误 系统就会停止执行 App Intent 并提示用户 继续在前台执行这个意图 我也可以提供一个可选的继续闭包 这个闭包会在主线程上执行 以便在 App 进入前台运行后 更新 App 的状态 这里 我使用这个闭包 把我的 App 导航到了错误界面 就像之前的那个例子 如果你想停止执行意图并要求 操作继续 你可以使用 needsToContinueInForegroundError 如果你想继续执行 App Intent 而不是完全停止这个执行 你可以使用另一个 API 在这种情况下 你可以调用 requestToContinueInForeground 方法 如果公交车 App 检测到 某条公交路线正在维护 而我想在 App 中 展现一个自定义 UI 来选择备用路线的时候 我可以使用这种方法 用户选好路线后 我就可以从我的 App 中返回更新后 的路线并继续执行 App Intent 这一次 我没有抛出错误 而只调用了一个 带有 try 和 await 的方法 传入的闭包会返回一个值 这个值可以在我的执行中返回 这样 我就可以在获取用户的输入信息后 继续执行 App Intent 这里 我采用了用户选好的备用路线 并返回了一个片段 显示这条路线的下一班公交车 简而言之 如果你想完全 停止执行 App Intent 你就使用抛出办法 反之 如果你想从用户那得到一个结果 并用这个结果 完成 App Intent 的执行 就用 requestToContinueInForeground 并等待它的结果
今年 我们还在 App Intents 中 增加了对 Apple Pay 的支持 你现在可以直接在执行方法中 启动 Apple Pay 交易 在执行中 使用 Apple Pay 非常简单 我先创建一个 PKPaymentRequest 实例 并配置好必要的信息 然后再使用 PKPaymentAuthorizationController 来呈现 Apple Pay 付款表单 并处理授权 我们使用一个保护语句检查 这个控制器是否成功呈现了 如果没有的话 我就会返回“无法完成支付”对话框 反之则成功付款了 最后 我们来深入了解一些 App Intents 和快捷指令 App 集成的更新 我们从集成了 App Intents 的 系统中所有不同的地方开始说起 App Intents 是一种 构建快捷指令操作的先进方法 App 快捷指令让用户能够使用 Siri 和快捷指令 App 更轻松地发现 和使用你 App 的功能 它还集成了专注模式过滤器 和 Apple Watch Ultra 上的操作按钮 由于集成了交互式实时活动 App Intents 在 iOS 17 中 得到了更广泛的应用 比如小组件配置、 交互性和 SwiftUI App 快捷指令也得到了发展 用以支持 聚焦 Top Hits 和自动化 所有这些集成代表着 相同的 App Intents 代码 在多种不同的方式中 都可以重复使用 由于现在 App Intents 已经深入 集成到了关键系统组件中 所以确保你创建的 App Intents 平稳运行就变得非常重要 提供一个不错的参数摘要对于确保 App Intents 在整个系统中显示 的美观度至关重要 编写参数摘要 使其读起来像一个句子 并把可选参数隐藏在折叠下面 然后由系统基于上下文 为你的参数摘要 确定最佳视觉表现 尽管我们希望 App Intents 在任何地方都能很好地运作 但可能会有一些情况 你需要把 App Intents 用在你的 App 或者交互式小组件里 并且避开系统的其他部分 举个例子 如果 App Intent 在 App 中调用了一个本地函数 而这个本地函数 无法生成一个快捷指令操作 在这种情况下 你可以把 App Intent 的 isDiscoverable 属性 设置为 false 我要在我的 Next Bus 小组件中 添加一个刷新按钮 从服务器中获取最新数据 尽管它承担了一定的作用 但无法成为有用的快捷指令操作 由于我只想在交互式小组件中 使用这个 App Intent 所以我把 isDiscoverable 设置为 false 请注意 标记为不可发现的 App Intents 也不能参与 App 快捷指令 我 App 中的意图执行得很快 但是不是所有的意图都是这样 今年 我们引进了一种新方法 给大家显示 长时间运行的意图的进展情况 要想了解进展 只需要让你的 App Intents 符合 ProgressReportingIntent 协议 你可以在 perform() 方法中 获取提供的进展对象 随着意图执行的推进 你可以通过设置 totalUnitCount 和增量 completedUnitCount 来更新进度 快捷指令 App 现在可以自动显示 App Intent 执行的进度 实施进度报告 对长时间运行的意图尤为重要 对用户来说 能够获得这种反馈尤为宝贵 因为这样他们就能知道 意图执行的推进情况 以及什么时候可以完成这个执行 今年我们也改进了 App 和 查找操作的集成方式 快捷指令用户喜欢通过特定条件 比如查找备忘录等操作 在 App 中查找内容 这些操作的输出结果可以 发送给其他快捷指令操作 比如发送邮件 来启用许多强大的工作流程 在 iOS 16 中 通过使用 EntityPropertyQuery 你可以为你的 App 自动获取查找操作 声明你希望用户能指定的条件 从 iOS 17 开始 你也可以使用 EnumerableEntityQuery 协议来代替 它非常简单 也很容易使用 使用 EnumerableEntityQuery 和在 allEntities() 方法中 返回实体所有可能的值一样简单 快捷指令和 App Intents 接下来 会自动生成查找操作 EnumerableEntityQuery 和 EntityPropertyQuery 的区别在于 我们使用 EntityPropertyQuery 向包括你在内的开发者发送条件 然后你代表用户进行搜索 这就意味着 你要经常返回一组有限的结果 有了 EnumerableEntityQuery 你可以给框架提供所有可能的实体 快捷指令会对其进行过滤 因为它会返回所有实体 EnumerableEntityQuery 使用起来很简单 但也针对少量实体进行了优化 它适用于 Safari 浏览器标签组等情况 但不适合大量实体的情况 而这也是 备忘录 App 的典型特点 EnumerableEntityQuery 同样不适用 于占据大量内存的大型实体 在这种情况下 你可以使用 EntityPropertyQuery 这样就可以在终端搜索 而不是一次性返回所有可能的实体 最后 我想再介绍一些 IntentDescription 的更新 这是一种 用来填写快捷指令 UI 的类型 在用户点击详情按钮获取 更多操作信息时会看到这个页面 IntentDescription 包括描述、 文本、类别名称和搜索关键词 在 iOS 17 中 Intent Description 类型 已经更新了一个新属性 叫作 resultValueName 这样你就可以为你的操作输出 提供一个更具描述性的名称 这里 “添加提醒” 为已创建并返回的提醒 提供了一个 resultValueName 叫作“新提醒” 当这里的“添加提醒”操作 和 Show Result Action 相连接时 Show Result action 中的参数 就会显示这个名称:“新提醒” 使用 IntentDescription 新初始化程序 就能提供 resultValueName 从 iOS 17 开始 你也可以为通过使用 EntityPropertyQuery 或 EnumerableEntityQuery 协议 生成的查找操作添加一个意图描述 要做到这一点 只需要在查询类型中 采用 findIntentDescription 属性 如果你使用 categoryName 对操作进行分类 生成的查找操作就会显示在 App 支持的操作列表里 你所需的类别下 简而言之 App Intents 是向系统和用户 展示 App 功能的好方法 如果你想深入了解 如何把 App Intents 转变为 App 快捷指令 以便用户可以立即使用 我推荐你观看讲座 “用 App 快捷指令突出你的 App” 今年 App Intents 让你可以构建 可配置的交互式小组件 和实时活动 并且和快捷指令 App 的深入集成 为开发者提供了更流畅的体验 非常期待看到你的 App 能够利用新的 App Intents 技术 为大家带来惊喜和愉悦 感谢大家观看
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。