ios - No se pudo convertir el valor del tipo ''NSTaggedPointerString'' a ''NSNumber''
swift double (5)
Tengo una estructura Swift como esta.
struct Usage {
var totalData: Double
var remainingTotalData: Double
init(jsonData: NSData) {
var jsonDict = [String: AnyObject]()
do {
jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String: AnyObject]
} catch {
print("Error occurred parsing data: /(error)")
}
totalData = jsonDict["totalfup"] as! Double
remainingTotalData = jsonDict["totalrem"] as! Double
}
}
De una API, obtengo la siguiente respuesta JSON.
Esta es la impresión de la variable
jsonDict
.
[
"totalfup": 96.340899,
"totalrem": 3548710948
]
Cuando intento asignar el valor de
totalfup
a la propiedad
totalData
,
totalData
este error.
No se pudo convertir el valor del tipo ''NSTaggedPointerString'' a ''NSNumber''
Alguien sabe por qué?
Intenté cambiar el tipo de propiedad a
float
y luego toda la estructura a clase, pero aún ocurre el problema.
Swift 4
let strStatus:String = dictProperty.value(forKey: "StatusType") as! String
let myStatus = Double.init(strStatus)
Actualizar
extension String {
func toDouble() -> Double? {
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
return numberFormatter.number(from: self)?.doubleValue
}
func toInt() -> Int? {
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
return numberFormatter.number(from: self)?.intValue
}
func toFloat() -> Float? {
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
return numberFormatter.number(from: self)?.floatValue
}
func toBool() -> Bool? {
let numberFormatter = NumberFormatter()
numberFormatter.locale = Locale(identifier: "en_US_POSIX")
return numberFormatter.number(from: self)?.boolValue
}
}
¿Por qué no usar los tipos nativos de Swift directamente?
import Foundation
struct Usage {
var totalData: Double = 0
var remainingTotalData: Double = 0
init(jsonData: NSData) {
do {
if let jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as? [String:Double] {
totalData = jsonDict["totalfup"] ?? 0
remainingTotalData = jsonDict["totalrem"] ?? 0
}
} catch {
print("Error occurred parsing data: /(error)")
}
}
}
if let data = "{/"totalfup/":96.340899,/"totalrem/":3548710948}".dataUsingEncoding(NSUTF8StringEncoding) {
let usage = Usage(jsonData: data)
dump(usage)
/*
▿ Usage
- totalData: 96.340899
- remainingTotalData: 3548710948.0
*/
}
Creo que esto podría ayudarte
totalData = Double(jsonDict["totalfup"] as! String)!
La razón de la falla es que el JSON devuelve valores de
String
, no números.
Si los datos JSON devueltos contienen solo estos dos pares de valores clave, declare el tipo como
[String:String]
que evita la conversión de tipos.
En cualquier caso, debe poner el código para actualizar las variables en la rama "buena" de la expresión
do - catch
.
struct Usage {
var totalData = 0.0
var remainingTotalData = 0.0
init(jsonData: NSData) { // Swift 3: Data
do {
let jsonDict = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String: String]
// Swift 3: let jsonDict = try NSJSONSerialization.jsonObject(with: jsonData) as! [String: String]
totalData = Double(jsonDict["totalfup"]!)
remainingTotalData = Double(jsonDict["totalrem"]!)
} catch {
print("Error occurred parsing data: /(error)")
}
}
}
La razón del error es
jsonDict["totalfup"]
es un String (
NSTaggedPointerString
es una subclase de
NSString
), por lo que debe convertir String a Double.
¡Asegúrate de atrapar la excepción y verificar el tipo antes de desenrollar forzosamente!
totalData = (jsonDict["totalfup"] as! NSString).doubleValue
Por seguridad, use
if let
:
if let totalfup = (dict["totalfup"] as? NSString)?.doubleValue {
// here, totalfup is a Double
}
else {
// dict["totalfup"] isn''t a String
}