SiriKit和付款域

自从SiriKit首次发布以来,Apple扩展了对许多域的支持。 让我们回顾一下付款域。 具体来说,帐户即余额即是快速余额检查。 阅读本教程后,以下内容将变得熟悉:

  • INSearchForAccountsIntent
  • INSearchForAccountsIntentResponse
  • INPaymentAccount

我们的目标是向Siri询问类似“ 我有多少钱? ”并获取要回复的帐户列表。


应用程序将包含3个主要部分:

  • 主要应用程序(主要目标;简单的单屏应用程序)
  • SiriKit扩展(与Siri交互的目标)
  • 共享库(帐户获取逻辑所在的位置); 在先前目标之间共享的代码。

首先,创建一个名为MyBank空项目( File> New> Project…> Single View App )。 其次,添加共享库( File> New> Target…> Cocoa Touch Framework )并使用QuickBalance作为名称。 我们的主要目标应取决于共享库。

要使Siri了解我们的应用程序,请启用Siri (在“ Project navigator ”选项卡中,选择project> Capabilities> Siri )。 接下来,选择“ Info.plist ”,添加带有自定义文本的新行“ Privacy — Siri Usage Description ”。

在某些时候,应用程序必须请求Siri的许可。 在我们的应用程序中,我们将其放入应用程序委托中。 打开AppDelegate.swift ,导入Intents框架并添加application(_:didFinishLaunchingWithOptions:)权限请求:

  import Intents ... func application(_ application:UIApplication,didFinishLaunchingWithOptions launchOptions:[UIApplication.LaunchOptionsKey:Any]?)->布尔{INPreferences.requestSiriAuthorization {如果status ==的状态。授权{print(“ Sello!Siri!” }} else {print(“ No Siri :(”)}}返回true} 

运行应用程序。 您应该看到空白屏幕和对话框

每个银行申请都应有帐户。 我们还创建了一些。 为了在主应用程序和Siri扩展之间共享代码,我们将域对象Account和逻辑放入QuickBalance框架内的服务器中获取帐户。 让我们创建一个名为Account的新类(在项目结构树中选择QuickBalance文件夹, File> New> File…> Swift File )。 我们使Account非常简单:

  public struct Account {public let name:String public let balance:Double} 

而且我们还需要一些服务来调用(在项目结构树中选择QuickBalance文件夹, File> New> File…> Swift File ),让我们在QuickBalanceServiceQuickBalanceService 。 我们的服务会延迟返回三个虚拟帐户(假装正在进行实际的网络通话):

 打开类QuickBalanceService {public init(){} public func quickBalanceAccounts(_completion:@escaping((__ accounts [Account])-> Void)){var accounts = [Account]()let account1 = Account(name:“主帐户”,余额:150.0)let account2 =帐户(名称:“储蓄帐户”,余额:300.0)let account3 =帐户(名称:“信用卡帐户”,余额:-100)account.append(account1)帐户。 append(account2)accounts.append(account3)sleep(3)完成(accounts)}} 

我们准备将一些Siri添加到我们的银行应用中。 让我们添加另一个名为QuickBalanceIntentsExtension目标( File> New> Target…> Intent Extension )。 现在取消选中“ 包括UI扩展”复选框,并为“ 起点”选择“ ”。 主动方案,如果它询问您。

这里还没有太多。 带有单个功能的单个文件IntentHandler

 覆盖func处理程序(用于意图:INIntent)->任何 

我们会尽快回到这里。

正如我之前提到的,Siri在许多域中运作(=您可能会问任何问题),但是我们只对帐户数据请求感兴趣。 让我们为支持的意图添加INSearchForAccountsIntent (扩展的Info.plist> NSExtension> NSExtensionAttributes> IntentsSupported>添加新项INSearchForAccountsIntent

当Siri识别出您的讲话在做某件事时,便会从这里开始。 因此,每当我们收到请求时 ,都应该处理它并提供响应 。 让我们在扩展中创建该类(选择扩展文件夹File> New> File…> Swift File ),命名为QuickBalanceRequestHandler 。 此类将调用我们的共享框架,并将我们的Account包装在Siri理解为INPaymentAccount 。 首先将Account扩展名添加到QuickBalanceRequestHandler文件中,不要忘记导入IntentsQuickBalance框架

 导入Intents导入QuickBalance扩展帐户{公共变量intentAccount:INPaymentAccount {返回INPaymentAccount(昵称:INSpeakableString(spokenPhrase:self.name),数字:nil,accountType:.unknown,OrganizationName:nil,余额:INBalanceAmount(amount:NSDecimalNumber(floatLiteral:余额),currencyCode:“ EUR”),secondaryBalance:nil)}} 

如您所见, INPaymentAccount有很多字段。 但是几乎所有的内容都是可选的,我们暂时不会涉及它们。 现在将QuickBalanceRequestHandler添加到文件末尾:

 类QuickBalanceRequestHandler:NSObject,INSearchForAccountsIntentHandling {函数句柄(意图:INSearchForAccountsIntent,完成:@escaping(INSearchForAccountsIntentResponse)->无效){QuickBalanceService()。quickBalanceAccounts {(帐户),让响应:INSearchForAccountsIntentRes = 0。 INSearchForAccountsIntentResponse(代码:.failureAccountNotFound,userActivity:.none)完成(响应)return} response = INSearchForAccountsIntentResponse(代码:.success,userActivity:.none)response.accounts = account.compactMap({return $ 0.intentAccount}完成) )}}} 

再次,这里不多。 只是尝试获取帐户。 如果没有运气,请返回.failureAccountNotFound代码,以便Siri可以正确答复(检查INSearchForAccountsIntentResponseCode枚举以获得更多选项)。 如果找到帐户,则将它们包装在INPaymentAccount并返回.success代码。

现在,我们准备好以适当的响应处理 Siri的请求 。 导航到IntentHandler文件,并将函数替换为:

 覆盖func处理程序(用于意图:INIntent)->可以吗?  {如果意图是INSearchForAccountsIntent {返回QuickBalanceRequestHandler()}返回.none} 

我们准备与Siri交谈。 但是我们不会。 因为现在您周围可能有人。 因此,让我们配置Xcode使其安静地运行并启动QuickBalanceIntentsExtension方案(Xcode>产品>方案>编辑方案…>运行>信息> Siri Intent Query ),询问“ How much money I have in MyBank app?

并启动QuickBalanceIntentsExtension方案。 你应该看到这样的东西

您可能会注意到,我们指定了有问题的应用程序。 尝试不指定,最初的回复可能是这样

最终,即使不指定Siri,Siri也会使用正确的应用程序。


目前为止就这样了。 来源在这里。 接下来,我们为帐户列表创建自定义UI,并尝试教Siri回答有关帐户的更具体的问题。