If you look closely the constructors of integers from string return optional values. So what you have is:
let totalprice = {
let a: Int? = Int(prodval)
let b: Int? = Int(proqty)
return a*b // Error
}()
a quick fix is to force-unwrap it using !
resulting in let totalprice = (Int(prodval))! * (Int(proqty))!
but I would not suggest it because it may crash your app.
A but more elegant solution is to use defaults:
let totalprice = {
let a: Int = Int(prodval) ?? 0
let b: Int = Int(proqty) ?? 0
return a*b
}()
But on the other hand why are you even using integers here? What if the price is not a whole number? I suggest you rather use decimal numbers to handle these cases:
let a = NSDecimalNumber(string: prodval)
let b = NSDecimalNumber(string: proqty)
let totalprice = a.multiplying(by: b)
This is now working with decimal numbers directly. To get a double value or integer value you would simply need to use it's properties totalprice.doubleValue
or totalprice.intValue
. But there is no need for that either. If you need to convert it back to string simply use formatters:
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencySymbol = "$"
let finalOutput: String = formatter.string(from: totalprice)
There are many possible solutions to this and if possible I would try to do it all with formatters and decimal numbers. For instance in your case something like the following might do the trick:
private func generateFormatter(currencySymbol: String = "$", decimalSeparator: String = ".") -> NumberFormatter {
let formatter = NumberFormatter()
formatter.currencySymbol = currencySymbol
formatter.decimalSeparator = decimalSeparator
formatter.numberStyle = .currency
return formatter
}
private func parseValue(_ input: String?, formatterInfo: (currencySymbol: String, decimalSeparator: String)) -> NSNumber? {
guard let input = input else { return nil }
let formatter = generateFormatter(currencySymbol: formatterInfo.currencySymbol, decimalSeparator: formatterInfo.decimalSeparator)
return formatter.number(from: input)
}
private func multiplyValues(_ values: [String?], formatterInfo: (currencySymbol: String, decimalSeparator: String)) throws -> NSNumber {
return try values.reduce(NSDecimalNumber(value: 1.0)) { result, value in
guard let parsedValue = parseValue(value, formatterInfo: formatterInfo) else {
throw NSError(domain: "Parsing values", code: 400, userInfo: ["dev_message": "Could not parse a value \(value ?? "[Null value]")"])
}
return NSDecimalNumber(decimal: result.decimalValue).multiplying(by: NSDecimalNumber(decimal: parsedValue.decimalValue))
}
}
let values = ["$1.2", "$1.6", "$2"]
let result = try? multiplyValues(values, formatterInfo: ("$", "."))
let parsedResult: String = {
guard let result = try? multiplyValues(values, formatterInfo: ("$", ".")) else { return "Could not produce result" }
return generateFormatter(currencySymbol: "$", decimalSeparator: ".").string(from: result) ?? "Could not format result"
}()
print(result ?? "No result")
print(parsedResult)
I hope the code speaks for itself and you can see it is easy to change/inject different formats/symbols.