The basic concept presented by Himanshu works fine, but your problem isn't necessarily making use of an appropriate formatter, but how to fix your input, as the formatter expects a NSNumber
and not a String
.
So a quick internet check had me looking at Remove all non-numeric characters from a string in swift
So I could take a String
, filter out all the "non numerical" junk and then make a Double
out of it.
let input = Double(value.filter("0123456789.".contains))
from there I was able to borrow the concept from Himanshu and make a simple format
function
func format(_ value: String, locale: Locale = Locale.current) -> String? {
guard let input = Double(value.filter("0123456789.".contains)) else { return nil }
//value.trimmingCharacters(in: .whitespacesAndNewlines)
let currencyFormatter = NumberFormatter()
currencyFormatter.usesGroupingSeparator = true
currencyFormatter.numberStyle = .currency
currencyFormatter.locale = locale
return currencyFormatter.string(from: NSNumber(value: input))
}
I then made use of a Playground to test it using
var testStr1 = "$30.01"
var testStr2 = "$ 30.01"
format(testStr1, locale: Locale(identifier: "en_US")) // $30.01
format(testStr2, locale: Locale(identifier: "en_US")) // $30.01
format(testStr1, locale: Locale(identifier: "fr_FR")) // 30,01 €
format(testStr2, locale: Locale(identifier: "fr_FR")) // 30,01 €
format(testStr1, locale: Locale(identifier: "de_DE")) // 30,01 €
format(testStr2, locale: Locale(identifier: "de_DE")) // 30,01 €
Now, if you specifically want to use USD(xxx)
as the format, then you could simply use a basic NumberFormatter
and generate your own String
from the resulting conversion of the input to a Double
I have read from several posts using a double or float is bad
So, yes, maintaining a currency value as a Double
or Float
is generally a bad idea, currency values are typically maintained as a Int
or Long
, but this is due to how Double
and Float
representation works in computers, for the, general, presentation, you should be fine, but each use case needs be assessed.