Reputation: 303
I have a Json (received as text) that I convert it like this:
if let jsonData = raw.data(using: String.Encoding.utf8) {
if let json = try JSONSerialization.jsonObject(with: jsonData, options: .allowFragments) {
let products = json["products"] as! [Dictionary<String, AnyObject>]
Products contains an array of products (also json), where I have keys which value can be String, Float, Double... one key has a value that it can be any kind of number.
This field when it is received on text from endpoint looks like this: \"min_size\":\"0.01\"
but also can have values like \"min_size\":\"1\"
, or \"min_size\":\"0.001\"
. After my json conversion looks like this (printing using po
):
▿ 1 : 2 elements
- key : "min_size"
- value : 1
Or
▿ 15 : 2 elements
- key : "min_size"
- value : 0.01
But then, when I'm trying to access it on my code (I want to read it as a float, independently if it is a 1 or a 0.01), I get this:
let k = item["min_size"] // contains > ▿ Optional<Any> - some : 0.01
let i = item["min_size"] as? Float // contains > nil
let j = item["min_size"] as? Int // contains > nil
let y = item["min_size"] as? NSString // contains > "0.01"
let z = y!.floatValue // contains > "0.009999997"
I'm new on Swift, and I don't understand what's going on here.
Any idea what I'm doing wrong?
Upvotes: 4
Views: 1459
Reputation: 21
Your dictionary has a value type of AnyObject
and your JSON min_size
value is a String
, you could convert String
into a Float
and if it does not exist provide a default value:
let y = Float(item["min_size"] as? String ?? "0") ?? 0
Upvotes: 2
Reputation: 303
Based on suggestions that are on comments, solution that I implemented is:
let min_size = (item["min_size"] as? String ?? "").convertFromJSONStringToFloat()
where I have two extensions for String and Float
extension String {
func convertFromJSONStringToFloat() -> Float? {
let partNumber = self.split(separator: ".")
return (Float(self)?.roundToDecimal((partNumber.count > 1) ? partNumber[1].count : 1))!
}
}
extension Float {
func roundToDecimal(_ fractionDigits: Int) -> Float {
let multiplier = pow(10, Double(fractionDigits))
return Float((Double(self) * multiplier) / multiplier)
}
}
Upvotes: 2