-2

I am having a problem using NumberFormatter. I would like for the variable output to only contain a certain amount of digits.

E.g. 3.14 instead of 3.14567899

I am am getting an error Ambiguous reference to member 'string(from:)':

func calculateLength() {

    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2

    print(startingLength)
    print(endingLength)
    if startingLength == "Feet" && endingLength == "Inches" {
        output = formatter.string(from: NSNumber(value: Double(lengthTextFieldValue) * 12) // This is where I am getting the error
        print(output)

        lengthOutputLabel.text = ("\(lengthTextFieldValue) ft = \(output) inches")
    }    
}

What is the proper way?

Michal
  • 15,429
  • 10
  • 73
  • 104
Neulio
  • 312
  • 2
  • 9
  • Double string initializer returns an optional. You need to unwrap it or use the nil coalescing operator. `Double(lengthTextFieldValue) ?? 0` Btw no need to initialize a new NSNumber object. You can use Formatter’s method `string(for: Any)` and pass a Double – Leo Dabus Feb 13 '20 at 13:16
  • I think you have missed ")" aht the end of code `output = formatter.string(from: NSNumber(value: Double(lengthTextFieldValue) * 12))` – OKMIN Feb 13 '20 at 13:19
  • @OKMIN I tried that and got an error saying `Cannot assign value of type 'String?' to type 'Double'` – Neulio Feb 13 '20 at 14:10

2 Answers2

0

The problem in the code lies in the line exactly you mentioned:

output = formatter.string(from: NSNumber(value: Double(lengthTextFieldValue)! * 12))

The main problem is that the initializer for the Double returns an optional value. That you can either mitigate by wrapping the initialization in an if let statement, such as:

if let myDouble = Double(lengthTextFieldValue) {
    // your code
}

Or by using the shorthanded version, given that there is a neutral number you are willing to accept - such as 0 or 1:

let myDouble = Double(lengthTextFieldValue) ?? 0

What you can also do when you have your Double initialized is to round it up to the number of decimal places you want:

extension Double {
    func rounded(toPlaces places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

Source

Michal
  • 15,429
  • 10
  • 73
  • 104
  • I am new to swift how do I add the `extension Double` . Is there anything else to add to it? – Neulio Feb 13 '20 at 17:54
  • @AmaniH nope, no need, put it in a separate file and you're good to go. You might need to just import Foundation at the top. – Michal Feb 13 '20 at 19:26
0

formatter.string() returns an optional value.
So you should check output is ether nil or non-nil.
? after Type(like String) means that values is optional. Optional value could has nil.

func calculateLength() {

    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.minimumFractionDigits = 2
    formatter.maximumFractionDigits = 2


    print(startingLength)
    print(endingLength)
    if startingLength == "Feet" && endingLength == "Inches" {
        if let output = formatter.string(from: NSNumber(value: Double(lengthTextFieldValue) * 12)) {
            print(output)
            lengthOutputLabel.text = ("\(lengthTextFieldValue) ft = \(output) inches")
        }
    }
}
OKMIN
  • 97
  • 5