You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Siri触发AppIntent时IntentCurrencyAmount参数循环询问问题

Siri调用AppIntent时IntentCurrencyAmount参数循环询问无法识别的问题解决

问题重现

在SwiftUI iOS应用中,通过Siri调用带IntentCurrencyAmount参数的AppIntent发起交易时,Siri会反复询问金额参数,且无法识别用户的语音回答,perform方法完全不会执行。但通过快捷指令的图形界面触发时,参数可以正常输入,功能完全正常。

已尝试的无效方案:

  • 尝试给参数设置默认值,但IntentCurrencyParameter不支持此操作
  • 固定货币为单一值"EUR"简化逻辑,无效
  • 添加needValueRequest,但因perform方法未触发而不起作用

核心原因

  1. 快捷指令短语未关联参数:当前的AppShortcut短语没有包含参数占位符,Siri无法识别指令中需要捕获金额参数,导致进入无限询问循环。
  2. Siri语音解析缺少明确指引:没有为参数提供自定义解析逻辑,当用户用自然语言回答时,Siri无法正确映射为IntentCurrencyAmount类型。

解决方案

1. 更新AppShortcut短语,添加参数占位符

修改快捷指令的触发短语,加入参数占位符,让Siri知道可以在指令中直接接收金额输入,同时支持后续询问时的解析:

struct TapAutoShortcuts : AppShortcutsProvider {
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: OpenTransaction(), 
      phrases: [
        "Lancer une transaction [de \(\.$amount)] avec \(.applicationName)",
        "Déclencher une transaction [de \(\.$amount)] via \(.applicationName)"
      ], 
      shortTitle: "Lancer une transaction", 
      systemImageName: "gear"
    )
  }
}

2. 添加参数解析方法,手动处理Siri输入

实现参数的resolve(for:)方法,帮助Siri将用户的语音回答转换为合法的IntentCurrencyAmount:

@Parameter(title: "Montant",
           currencyCodes: ["EUR"],
           inclusiveRange: (lowerBound: 0.01, upperBound: 100000000),
           requestValueDialog: IntentDialog("Une transaction de quel montant ?")
)
var amount: IntentCurrencyAmount

// 添加参数解析方法
func resolveAmount(for intentParameter: IntentParameter, with completion: @escaping (IntentCurrencyAmount?) -> Void) {
  guard let userInput = intentParameter.value as? String else {
    completion(nil)
    return
  }
  let numberFormatter = NumberFormatter()
  numberFormatter.locale = Locale(identifier: "fr_FR")
  numberFormatter.numberStyle = .decimal
  if let number = numberFormatter.number(from: userInput) {
    let currencyAmount = IntentCurrencyAmount(amount: NSDecimalNumber(decimal: number.decimalValue), currencyCode: "EUR")
    completion(currencyAmount)
  } else {
    completion(nil)
  }
}

3. 确保Siri语言与参数本地化匹配

因为参数标题和提示语用法语,需要将设备的Siri语言设置为法语,避免语音识别的语言不匹配问题。

修改后的完整代码

import AppIntents

struct OpenTransaction : AppIntent {
  static var title: LocalizedStringResource = "Start a transaction"
  
  static var openAppWhenRun: Bool = true
  
  @Parameter(title: "Montant",
             currencyCodes: ["EUR"],
             inclusiveRange: (lowerBound: 0.01, upperBound: 100000000),
             requestValueDialog: IntentDialog("Une transaction de quel montant ?")
  )
  var amount: IntentCurrencyAmount
  
  // 参数解析方法
  func resolveAmount(for intentParameter: IntentParameter, with completion: @escaping (IntentCurrencyAmount?) -> Void) {
    guard let userInput = intentParameter.value as? String else {
      completion(nil)
      return
    }
    let numberFormatter = NumberFormatter()
    numberFormatter.locale = Locale(identifier: "fr_FR")
    numberFormatter.numberStyle = .decimal
    if let number = numberFormatter.number(from: userInput) {
      let currencyAmount = IntentCurrencyAmount(amount: NSDecimalNumber(decimal: number.decimalValue), currencyCode: "EUR")
      completion(currencyAmount)
    } else {
      completion(nil)
    }
  }
  
  @MainActor
  func perform() async throws -> some IntentResult {
    print(amount)
    // 这里调用自研交易框架逻辑
    return .result()
  }
  
  static var parameterSummary: some ParameterSummary {
    Summary("Lancer une transaction de \(\.$amount)")
  }
}

struct TapAutoShortcuts : AppShortcutsProvider {
  static var appShortcuts: [AppShortcut] {
    AppShortcut(
      intent: OpenTransaction(), 
      phrases: [
        "Lancer une transaction [de \(\.$amount)] avec \(.applicationName)",
        "Déclencher une transaction [de \(\.$amount)] via \(.applicationName)"
      ], 
      shortTitle: "Lancer une transaction", 
      systemImageName: "gear"
    )
  }
}

内容的提问来源于stack exchange,提问作者EliteSquadron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 20:51:09