Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Could not cast value of type 'NSTaggedPointerString' to 'NSNumber'

I have a Swift struct like this.

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
    }
}

From an API, I get the following JSON response. This is the println of the jsonDict variable.

[
    "totalfup": 96.340899, 
    "totalrem": 3548710948
]

When I try to assign the value of the totalfup to the property totalData, I get this error.

Could not cast value of type 'NSTaggedPointerString' to 'NSNumber'

Anyone knows why? I tried changing the property type to float and then the whole struct to class but still the issue occurs.

like image 202
Isuru Avatar asked Oct 23 '15 09:10

Isuru


3 Answers

The reason of the error is jsonDict["totalfup"] is a String (NSTaggedPointerString is a subclass of NSString) , so you should convert String to Double.

Please make sure, catch exception and check type before force-unwrap !

totalData = (jsonDict["totalfup"] as! NSString).doubleValue

For safety, using if let:

// check dict["totalfup"] is a String?
if let totalfup = (dict["totalfup"] as? NSString)?.doubleValue {
  // totalfup is a Double here 
}
else {
  // dict["totalfup"] isn't a String
  // you can try to 'as? Double' here
}
like image 180
tuledev Avatar answered Nov 18 '22 04:11

tuledev


I think this could help you

totalData = Double(jsonDict["totalfup"] as! String)!
like image 32
Hwei Avatar answered Nov 18 '22 03:11

Hwei


The failure reason is that the JSON returns String values, not numbers.

If the returned JSON data contains only these two key value pairs declare the type as [String:String] that avoids the type casting.

In any case you have to put the code to update the variables into the "good" branch of the do - catch expression.

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)")
        }
    }
}
like image 4
vadian Avatar answered Nov 18 '22 04:11

vadian