【问题标题】:Siri Integration for payments issue支付问题的 Siri 集成
【发布时间】:2016-10-24 09:34:51
【问题描述】:

在我的应用程序中,我只支持欧元和美元货币。因此,例如,当用户尝试使用 Siri 向英镑付款时,我要求他在欧元和美元之间进行选择。

之后我在屏幕上看到:

  • 100 美元
  • 100 欧元

如果我在intent.currencyAmount!.currencyCode 中选择 100 美元,我总是有 GBP(但用户选择了美元)。很奇怪。

这是我的代码:

func resolveCurrencyAmount(forSendPayment intent: INSendPaymentIntent, with completion: @escaping (INCurrencyAmountResolutionResult) -> Void) {
        if let currencyAmount = intent.currencyAmount { // need to check if we have proper value
            if let amount = currencyAmount.amount {

                if amount.doubleValue == 0 { // wrong amount
                    completion(INCurrencyAmountResolutionResult.unsupported())
                    return
                }

                if let currencyCode = currencyAmount.currencyCode {
                    if let _ = EnumCurrency(rawValue: currencyCode) { // we found currency code that we know
                        completion(INCurrencyAmountResolutionResult.success(with: INCurrencyAmount(amount: NSDecimalNumber(value: abs(amount.doubleValue)), currencyCode: currencyCode)))
                        return
                    }
                }


                // if we are here so we don't have proper currency, try to offer user to choose the same amount but with all possible currencies
                let disambiguationArray: [INCurrencyAmount] = EnumCurrency.allValues.map({ (currency) -> INCurrencyAmount in
                    return INCurrencyAmount(amount: NSDecimalNumber(value: abs(amount.doubleValue)), currencyCode: currency.rawValue)
                })
                completion(INCurrencyAmountResolutionResult.disambiguation(with: disambiguationArray))
            }
        }
        else { // we don't have value
            completion(INCurrencyAmountResolutionResult.needsValue())
        }
    }

enum EnumCurrency : String {
    case EUR = "EUR"
    case USD = "USD"

    static let allValues = [EUR, USD]
}

更新:如何重现(根据大卫的问题):

1) 创建一个新的意图扩展

2) 在 plist 文件中只留下一种意图:http://take.ms/pt16N

3) 您的 IntentHandler 类(将由 xCode 创建)必须确认 INSendPaymentIntentHandling 协议

4) 在 IntentHandler 类中添加:

func resolveCurrencyAmount(forSendPayment intent: INSendPaymentIntent, with completion: @escaping (INCurrencyAmountResolutionResult) -> Void) {
            if let currencyAmount = intent.currencyAmount { // need to check if we have proper value
                if let amount = currencyAmount.amount {

                    if amount.doubleValue == 0 { // wrong amount


                 completion(INCurrencyAmountResolutionResult.unsupported())
                    return
                }

                if let currencyCode = currencyAmount.currencyCode {
                    if let _ = EnumCurrency(rawValue: currencyCode) { // we found currency code that we know
                        completion(INCurrencyAmountResolutionResult.success(with: INCurrencyAmount(amount: NSDecimalNumber(value: abs(amount.doubleValue)), currencyCode: currencyCode)))
                        return
                    }
                }


                // if we are here so we don't have proper currency, try to offer user to choose the same amount but with all possible currencies
                let disambiguationArray: [INCurrencyAmount] = EnumCurrency.allValues.map({ (currency) -> INCurrencyAmount in
                    return INCurrencyAmount(amount: NSDecimalNumber(value: abs(amount.doubleValue)), currencyCode: currency.rawValue)
                })
                completion(INCurrencyAmountResolutionResult.disambiguation(with: disambiguationArray))
            }
        }
        else { // we don't have value
            completion(INCurrencyAmountResolutionResult.needsValue())
        }
    }

enum EnumCurrency : String {
    case EUR = "EUR"
    case USD = "USD"

    static let allValues = [EUR, USD]
}

// MARK: - Confirm

    func confirm(sendPayment intent: INSendPaymentIntent, completion: @escaping (INSendPaymentIntentResponse) -> Void) {
// success
        completion(INSendPaymentIntentResponse(code: INSendPaymentIntentResponseCode.success, userActivity: nil))

}

// MARK: - Handle

    func handle(sendPayment intent: INSendPaymentIntent, completion: @escaping (INSendPaymentIntentResponse) -> Void) {

// just for test
completion(INSendPaymentIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity))
}

5) 你可以用 Siri 启动:你会看到,如果你选择中国货币或任何其他非常规货币,然后我在代码中让你在 EUR 和 USD 之间进行选择,但之后在 RESOLVE 函数中(调用时调用siri 想在更多时间解析货币)你会得到中国货币(所以你不需要像大卫问的那样为按钮添加任何代码,因为所有按钮界面都将由 Siri 提供)

【问题讨论】:

  • 我没有看到剪断的短代码有错误。也许您想发布Button 的代码或任何需要用户交互的元素。
  • 没有错。我认为这可能是苹果的错误,因为很奇怪,如果我选择 USD ,我会立即从 Siri 获得 GBP 货币
  • 好吧,但是如果你不想发布代码,假设你是对的,并且进一步假设苹果框架中存在一个错误,你对这个线程有什么期望?跨度>
  • 我为您更新了说明。如您所见,您不需要任何按钮代码,因为所有按钮界面都将由 Siri 提供。因此,您可以尝试重现相同的问题,但在您需要创建 Intents 扩展之前。如果 Apple 框架中存在错误,我认为可能有任何解决方法,可以让代码正常工作

标签: ios swift ios10 siri sirikit


【解决方案1】:

我创建了这个问题: Siri and wrong currency

您需要做的就是确认用户选择的货币。 您的确认方法执行错误,您应该使用以下方式确认货币:

let response = INSendPaymentIntentResponse(code: .ready, userActivity: nil)
response.paymentRecord = INPaymentRecord(
    payee: intent.payee, 
    payer: nil, 
    currencyAmount: intent.currencyAmount, 
    paymentMethod: nil, 
    note: nil, 
    status: .pending, 
    feeAmount: nil)
completion(response)

【讨论】:

  • 您能否添加完整的代码以及解析(如果有)、确认、处理方法? (所以我可以试试你的代码,因为我的问题发生在 confirm 方法之前,它发生在 Resolve 方法中,所以如果我的 resolve 方法保持不变,Confirm 方法将永远不会被调用)。在你的问题中,@Reem 用户说这个解决方案对他没有帮助,所以我只想尝试整个代码
  • 我想了想,不明白:如果我没有currencyAmount的resolve方法,我不能只确认他的货币,因为他可以选择GBP货币,但应用程序没有'不支持。但是如果我有 resolveCurrencyAmount 方法,我不明白如何在这个方法中确定,当我需要返回完成时(INCurrencyAmountResolutionResult.success),因为我遇到问题的唯一情况是货币是英镑,但在这种情况下我会总是要求用户在可能的货币之间进行选择,这将是无穷无尽的。所以如果你能给出你几乎完整的代码,那就太好了
  • 在代码中添加了注释,您应该在其中创建 INpaymentRecord
  • 1) 在这种情况下不起作用,因为正如我之前所说,确认函数永远不会被调用,因为用户将无休止地在 Siri 中看到窗口在欧元和美元之间进行选择(因为在用户选择美元后的解决方法,我将获得 GPB,这就是为什么我无休止地让用户在货币之间进行选择 2)请发布您的 sendMoneyIntentHandlingProtocol 的完整代码(您可以删除非常个人且不是非常重要的代码部分)))3)请不要'不要在我的代码中进行编辑(因为 stackoverflow 的编辑器不允许这样做并且很难看到您的编辑
【解决方案2】:

在 confirmSendPayment 方法中,创建 INSendPaymentIntentResponse 实例并将 INPaymentRecord 实例分配给 paymentRecord 属性。我做了一个辅助方法来做这件事。

func confirm(sendPayment intent: INSendPaymentIntent, completion: (INSendPaymentIntentResponse) -> Void) {
    let response = INSendPaymentIntentResponse(code: .Ready, userActivity: nil)
    response.paymentRecord = getPaymentRecord(fromIntent: intent)
    completion(response)
}

private func getPaymentRecord(fromIntent intent: INSendPaymentIntent) -> INPaymentRecord? {
    let currencyAmount = INCurrencyAmount(amount: intent.currencyAmount?.amount ?? 0.0, currencyCode: "INR")
    return INPaymentRecord(payee: intent.payee, payer: nil, currencyAmount: currencyAmount, paymentMethod: nil, note: nil, status: .Pending)
}

希望这会有所帮助。

【讨论】:

  • 如果用户没有提供金额你用INR货币分配0,但我需要用户输入金额和货币,所以我需要resolveAmount函数,但如果我有这个功能,确认功能永远不会如果货币错误则执行(但通常是错误的)
  • 我没明白你所说的“如果货币错误,确认功能将不会执行”??
  • 因为如果货币错误,我会要求在 EUR 和 USD 之间进行选择,例如用户会选择 EUR,但 iOS 会认为他选择了 GBP,这就是为什么用户会看到无穷无尽的选择方法来选择货币
猜你喜欢
  • 1970-01-01
  • 2014-07-08
  • 1970-01-01
  • 2018-09-11
  • 2012-09-03
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 2011-09-06
相关资源
最近更新 更多