Cannot convert value of type 'String' to type 'NSNumber' in coercion

Hello
I'm trying to use a formatter on a String but it is giving me this error
Cannot convert value of type 'String' to type 'NSNumber' in coercion, is there a simple and short way to fix it?
Here is the code

Code Block
import SwiftUI
struct TemperatureView: View {
@State private var inputValue = ""
let inputUnits = [
"celsius [°C]",
"kelvin [K]",
"fahrenheit [°F]"
]
let outputUnits = [
"celsius [°C]",
"kelvin [K]",
"fahrenheit [°F]"
]
@State private var inputUnitValue = 0
@State private var outputUnitValue = 1
var after: String{
var input: Measurement<UnitTemperature>
var output: String = ""
switch inputUnits[inputUnitValue] {
case "celsius [°C]": input = Measurement(value: Double(inputValue) ?? 0, unit: .celsius)
case "kelvin [K]": input = Measurement(value: Double(inputValue) ?? 0, unit: .kelvin)
case "fahrenheit [°F]": input = Measurement(value: Double(inputValue) ?? 0, unit: .fahrenheit)
default: input = Measurement(value: Double(inputValue) ?? 0, unit: UnitTemperature.celsius)
}
switch outputUnits[outputUnitValue] {
case "celsius [°C]": output = outputFormatter.string(from: input.converted(to: .celsius))
case "kelvin [K]": output = outputFormatter.string(from: input.converted(to: .kelvin))
case "fahrenheit [°F]": output = outputFormatter.string(from: input.converted(to: .fahrenheit))
default: output = String(describing: input.converted(to: UnitTemperature.celsius))
}
return output
}
@Environment(\.presentationMode) var presentationMode
let outputFormatter: MeasurementFormatter = {
let nf = NumberFormatter()
nf.locale = Locale.current
nf.usesSignificantDigits = true
let mf = MeasurementFormatter()
mf.numberFormatter = nf
mf.unitOptions = .providedUnit
return mf
}()
var body: some View {
NavigationView{
Form{
Section(header: Text("Enter your Input value")){
TextField("Have a goal?", text: $inputValue)
.keyboardType(.decimalPad)
}
Section(header: Text("Input")){
Picker("Input values", selection: $inputUnitValue){
ForEach(0..<inputUnits.count){ item in
Text(inputUnits[item])
}
}
}
Section(header: Text("Output")){
Picker("Output values", selection: $outputUnitValue){
ForEach(0..<outputUnits.count){ item in
Text(outputUnits[item])
}
}
}
Section(header: Text("Check your Output value")){
Text("\(after as NSNumber, formatter: outputFormatter)")
}
}
.navigationBarTitle("Temperature")
.navigationBarItems(trailing:
Button(action: {
presentationMode.wrappedValue.dismiss()
}) {
Image(systemName: "xmark").font(.title).foregroundColor(.blue)
}
)
}
}
}

The error is at line 80/81

Thank you for your time

In your code, after is a String already formatted.
And outputFormatter is a MeasurementFormatter for Measurement, not for NSNumber.

So, you have several options:
  • Show after directly in line 80 -- Text("\(after)") (Or simply Text(after))

  • Change the definition of after to return Measurement<UnitTemperature>, and use the outputFormatter as is

Text("\(after, formatter: outputFormatter)") (No as NSNumber)
  • Change the definition of after to return some numeric type (such as Double), and change the outputFormatter to return NumberFormatter and use line 80 as is

(With this option, you will loose unit from shown text.)
  • ...

Anyway, you need to make 3 things consistent:
  • after

  • outputFormatter -- this needs to be able to format the type of after

  • line 80 -- if after is String, do not use outputFormatter. Else, you need to use the right as casting and the right formatter

Cannot convert value of type 'String' to type 'NSNumber' in coercion
 
 
Q