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

IosSwiftDoubleNsjsonserialization

Ios Problem Overview


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.

Ios Solutions


Solution 1 - Ios

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
}
    

Solution 2 - Ios

I think this could help you

totalData = Double(jsonDict["totalfup"] as! String)!

Solution 3 - Ios

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

Solution 4 - Ios

Tested and Working for Swift 5.0.

I had the same problem.

This worked for me.

// check dict["dummy"] is a String first
if let receivedData = (dict["dummy"]).doubleValue {
  // add more code in case the condition is true
}
else {
 // add more code in case the condition is false
}

It is really helpful when you want to compare the received data or just check the value like the following example.

let receivedData = (results["data"]!).doubleValue

if (receivedData == 0){
      self.label.text = "Nothing seem to be added yet!"
}

Solution 5 - Ios

String interpolation

I posted my answer in a similar thread.

if let jsonDict_any = jsonDict["totalfup"], 
   let jsonDict_double = Double("\(jsonDict_any)") {
   //..
}

Essentially, this avoids having to try multiple typecastings. By checking first for its existence, we can can then use string interpolation, then try casting it to a Double.

Warning:

As @Alexander pointed out, this solution allows any Type to become a String and be checked for a Double value. Only use this if you're not concerned about the value's Type prior to interpolation.

Solution 6 - Ios

why not use Swift's native types directly?

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

Solution 7 - Ios

#Swift 4

    let strStatus:String = dictProperty.value(forKey: "StatusType") as! String
    let myStatus = Double.init(strStatus)
    

#Update

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionIsuruView Question on Stackoverflow
Solution 1 - IostuledevView Answer on Stackoverflow
Solution 2 - IosHweiView Answer on Stackoverflow
Solution 3 - IosvadianView Answer on Stackoverflow
Solution 4 - IosYogView Answer on Stackoverflow
Solution 5 - IosMerricatView Answer on Stackoverflow
Solution 6 - Iosuser3441734View Answer on Stackoverflow
Solution 7 - IosVivekView Answer on Stackoverflow