简体   繁体   中英

trying to convert a string to a decimal for iOS 13

I have an app that this was all working correctly before iOS 13. I've checked a few posts but they seem to be saying what I have already done.

I'm passing a string that has currency symbols and formatting, and I want to strip that and use the string value.

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!
    }

}

An example of a string that I am passing: $300.00 the $ always triggers a return of nil. If I pass 300.00, then the converter works just fine. But I need to be able to check for any currency the user has set for their device.

The currency codes that I am checking are the ones Apple supplies in the var currencyCode: String? { get } var currencyCode: String? { get } options is just where I am storing those codes.

The numberFormatter produces nil every time, and it seems because my decimal is not being stripped of its formatting.

Again this worked before iOS 13, so I am guessing something changed on Apple's side and I just might not have come acrossed it yet.

UPDATE Here is a user seniaro. The user enters an amount. If the user hits save right away, I take the amount and convert it into a decimal to save in coredata. But if the user dismisses the keyboard, I take that amount and convert it into a string to display the currency symbol. I allow the user to set their currency, so using the locale doesn't work for me, as sometimes they are not using that system. So after the keyboard is dismissed and their amount is displayed with the correct formatting, I have it programmed that if they would happen to change their amount and once again dismiss the keyboard, and the same steps are repeated. The currency symbols are stripped and the string is converted into a decimal.

I hope this better gives you an idea of how this works in my app.

UPDATE I've added an if/else statement to see if the locale has been set or if it comes back nil, and if so to set it to the Locale.current

Assuming the input string is using the device's current locale you can create a NumberFormatter with Locale.current and set the numberStyle to currency.

I used a small playground to test it:

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

This prints:

  • 300
  • 3000.04
  • Not a value
  • Not a value
  • 3000000

If you keep getting nil as a result your device's locale is different as the sample string number you are using in the question ($300).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM