Let's say you want to display to user that something cost 50 dollars. You might want to do something like this:
let price = 50 print("\(price) $")
Please, never ever do stuff like this 🛑
This is very naive solution that will easily confuse users and does not scale well. Because in some countries dollar sign or other currency signs are put in front of the price. Sometimes there might not be a space. With bigger sums or fractions some locales may use
. while others use
, or even combination of the two.
The solution is also not to remember all these rules or give up. The solution is called
All you have to do is to use it and be mindful of small number of configuration options. Everything else is taken care of by the system.
The very basic usage looks like this:
let formatter = NumberFormatter() formatter.numberStyle = .currency
You create instance of the formatter and set its style to
And then use
string method to get formatted string as a currency. The drawback here is that you have to use
NSNumber which can be created from
Double and the return type is optional string.
In practice I don't think the string will ever by
nil when this method is called with valid
NSNumber instance but to be sure I am often using it like this:
print(formatter.string(from: NSNumber(value: 548.5)) ?? "n/a")
Better way would be to create centralized util class to handle formatting and internally check that result of the
string(from: NSNumber) is not
nil and if for some reason is
nil crash you app with
assert during debug to get a chance to investigate the issue further.
The above formatter will use user's current Locale to select currency symbol and style for the price. This may be what you want but if your app is designed to work in multiple countries and is getting data from a server, then you should set the currency manually for formatter to be sure that if your server sends price of 20 Eur for example the user will see
20 € and not something like
20 zł because they are from Poland..
You can set currency like this:
formatter.currencyCode = "EUR" formatter.currencyCode = "USD" // and so on..
NumberFormatter also allows you to specify
locale which can be useful during testing to preview how the numbers are going to look like for people on other countries. In practice you shouldn't set this unless you have very important reason for doing so.
formatter.locale = Locale(identifier: "de-DE") // lets check how will prices look for people from Germany
If you don't want to show prices with fractional part. Meaning you want to show
10 and not
10,12. You can set the property
maximumFractionDigits to specify the maximum number of fraction digits. Set it to
0 to show none 🙂
Thanks for reading!