0

The problem is my API response returns orders[indexPath.row].price as a String. The string is actually a double value like 3.55973455234. I need to convert this value to something like 3.56 and display in UI label. I have been pulling my hair since morning to achieve this. Why is Swift so horrible at conversions?

        cell.lblPayValue.text = orders[indexPath.row].price
Rashwan L
  • 38,237
  • 7
  • 103
  • 107
Ackman
  • 1,562
  • 6
  • 31
  • 54

3 Answers3

1

Just do it like this:

let formatter = NumberFormatter()
formatter.numberStyle = .currency

if let price = Double(orders[indexPath.row].price), let formattedPrice = formatter.string(for: price) {
    cell.lblPayValue.text = formattedPrice
}
  1. So you get the double value first with the if-let
  2. Then you use it to set your cell.lblPayValue.text
  3. You use the formatter to get a currency format on your Double
Rashwan L
  • 38,237
  • 7
  • 103
  • 107
1

You could also use NumberFormatter but you would need to convert it back to a NSNumber...

let formatter = NumberFormatter()
formatter.numberStyle = .decimal
formatter.maximumFractionDigits = 2
formatter.locale = Locale(identifier: "en_US")

if let number = formatter.number(from: orders[indexPath.row].price) {
    cell.lblPayValue.text = formatter.string(from: number)
}

But please don't create N NumberFormatter. Create one and store it somewhere.

Adam
  • 4,266
  • 1
  • 21
  • 21
  • Hey It doesn't seem to be hitting the if statement can we do something so that it always goes within the if block? – Ackman Oct 16 '17 at 20:27
  • Could be a problem with the decimal separator. When parsing, locale should be always set correctly. – Sulthan Oct 16 '17 at 20:34
  • Maybe your number is formatted in a different manner than the locale suppose (because NumberFormatter is locale specific). Try with the updated code. Anyway, try to not use this solution because you'll create *maybe* unnecessary ressources. But NumberFormatter still offers some advantages. – Adam Oct 16 '17 at 20:35
  • No problem. But as I said, I hope you don't create a NumberFormatter inside `cellForRowAtIndexPath` because it would create a formatter for each cell. Try to create one somewhere (`viewDidLoad` if you want), store it as a property and access it everywhere. – Adam Oct 16 '17 at 20:40
  • @Ackman don't use decimal. It is a currency. You should display it accordingly to the user Locale. To convert from string to double just use the Double initializer – Leo Dabus Oct 16 '17 at 20:40
  • 1
    Noted. Thanks a ton :) I see we do not need the formatter instance being created every time. – Ackman Oct 16 '17 at 20:42
  • @Ackman Oh yeah. If you want fancy formatting (currencies) try to change the `numberStyle` to something else. But don't forget that it is locale specific. – Adam Oct 16 '17 at 20:42
  • Hey what do I do if I want a "$" sign in front of the text amount on label? – Ackman Oct 16 '17 at 20:45
  • no worries got it did : cell.lblPayValue.text = "$" + cell.lblPayValue.text! Thanks a ton – Ackman Oct 16 '17 at 20:48
1

Conversions are pretty straightforward IMHO. You can create a new Double by using the initialiser with a string. Then you have an optional Double. This can then be converted to a formatted String. So...

    let price: String = "3.55973455234" // your price
    let text = String(format: "%.2f", Double(price)!)
    print(text) // prints 3.56
CodeR70
  • 447
  • 3
  • 2