12

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

之后在屏幕上我看到:

  • 100 美元
  • 100 欧元

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

这是我的代码:

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

4

2 回答 2

3

我创建了这个问题: Siri 和错误的货币

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

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)
于 2016-11-03T14:40:46.560 回答
0

在 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)
}

希望这可以帮助。

于 2017-02-06T09:06:24.940 回答