ios - 尝试将字符串转换为 iOS 13 的小数

标签 ios swift nsnumberformatter

我有一个应用程序,它在 iOS 13 之前一切正常。我检查了一些帖子,但他们似乎在说我已经做过的事情。

我正在传递一个包含货币符号和格式的字符串,我想去掉它并使用字符串值。

func changeCurrencyToDecimal(stringNumber:String) -> Decimal {


    let numberFormatter = NumberFormatter()

    // Pull apart the components of the user's locale
    var locComps = Locale.components(fromIdentifier: Locale.current.identifier)
    // Set the specific currency code
    locComps[NSLocale.Key.currencyCode.rawValue] = options?.currencyCode // or any other specific currency code
    // Get the updated locale identifier
    let locId = Locale.identifier(fromComponents: locComps)
    // Get the new custom locale
    //numberFormatter.locale = Locale(identifier: locId)

    if(options?.currencyCode == nil) {
           print("There is no currency code so use the default locale")
           numberFormatter.locale = Locale.current
       }
       else{
           print("We have a currency code!")
           numberFormatter.locale = Locale(identifier: locId)
       }

    numberFormatter.numberStyle = .currency
    numberFormatter.currencySymbol = ""
    numberFormatter.decimalSeparator = ","  

    print("\(stringNumber) is the number being passed")

    let number = numberFormatter.number(from: stringNumber)

    // check to see if the number is nil and if so, return 0.

    print("\(number) is the number converted")
    if number == nil{
        return 0
    }
    else{
        print("\(number!) is the number")
        let amount = number?.decimalValue
        return amount!
    }

}

我传递的字符串示例:$300.00 $ 总是触发 nil 的返回。如果我通过 300.00,则转换器工作正常。但我需要能够检查用户为其设备设置的任何货币。

我正在检查的货币代码是 Apple 在 var currencyCode: String? { get } 选项就是我存储这些代码的地方。

numberFormatter 每次都生成 nil,这似乎是因为我的小数点没有被删除其格式。

这在 iOS 13 之前再次起作用,所以我猜 Apple 方面发生了一些变化,我可能还没有遇到它。

更新 这是一个用户 seniaro。用户输入金额。如果用户立即点击保存,我会获取金额并将其转换为小数以保存在 coredata 中。但是,如果用户关闭键盘,我会获取该金额并将其转换为字符串以显示货币符号。我允许用户设置他们的货币,所以使用区域设置对我不起作用,因为有时他们不使用该系统。因此,在关闭键盘并以正确的格式显示其金额后,我对其进行了编程,如果他们碰巧更改了金额并再次关闭键盘,则重复相同的步骤。去除货币符号并将字符串转换为小数。

我希望这能让您更好地了解它在我的应用中的工作原理。

更新 我添加了一个 if/else 语句来查看语言环境是否已设置或返回 nil,如果是则将其设置为 Locale.current

最佳答案

假设输入字符串使用设备的当前区域设置,您可以使用 Locale.current 创建一个 NumberFormatter 并将 numberStyle 设置为货币。

我用一个小 Playground 来测试它:

import Foundation

func changeCurrencyToDecimal(_ stringNumber: String) -> Decimal? {
  let numberFormatter = NumberFormatter()
  numberFormatter.numberStyle = .currency

  let number = numberFormatter.number(from: stringNumber)
  return number?.decimalValue
}

let numbersFormatted = ["$300", "$3,000.04", "3.000,04", "Wazaa", "3000000"]
numbersFormatted
  .map { changeCurrencyToDecimal($0) }
  .forEach { print($0 ?? "Not a value") }

这打印:

  • 300
  • 3000.04
  • 不是一个值
  • 不是一个值
  • 3000000

如果您一直收到 nil 结果,您设备的区域设置与您在问题中使用的示例字符串编号 ($300) 不同。

关于ios - 尝试将字符串转换为 iOS 13 的小数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58151850/

相关文章:

ios - Unity-iOS : Separating Unity iOS project into any existing iOS Xcode project

ios - 在没有开发者注册的情况下转移应用程序?

html - 在索引处的字符串中插入字符串(快速)

ios - 如何根据键对数组进行排序?

ios - Xcode swift - Unresolved 标识符错误

ios - 处理 Firebase 查询中由于元素数量较多而导致的内存使用情况

swift - 无法将类型 'String' 的值转换为预期的参数类型 'NSNumber'

swift - 按国家 ISO 获取 NumberFormatter 货币

ios - UITextfield 验证 1 - 100 之间的国家/地区货币

ios - CGMutablePath X 和 Y 应该接受其 View 的边界