ios 无法将“NSTaggedPointerString”类型的值转换为“NSNumber”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33299202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 08:04:38  来源:igfitidea点击:

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

iosswiftdoublensjsonserialization

提问by Isuru

I have a Swift struct like this.

我有一个这样的 Swift 结构。

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 jsonDictvariable.

从 API 中,我得到以下 JSON 响应。这是jsonDict变量的 println 。

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

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

当我尝试将 的值分配给totalfup属性时totalData,出现此错误。

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

无法将“NSTaggedPointerString”类型的值转换为“NSNumber”

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

有谁知道为什么?我尝试将属性类型更改为float,然后将整个结构更改为类,但问题仍然存在。

回答by tuledev

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

错误的原因jsonDict["totalfup"]是 String ( NSTaggedPointerStringis a subclass of NSString) ,所以你应该将String转换为Double。

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

请确保在强制解包之前捕获异常并检查类型!

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

For safety, using if let:

为了安全,使用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
}

回答by Hwei

I think this could help you

我认为这可以帮助你

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

回答by vadian

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

失败的原因是 JSON 返回的是String值,而不是数字。

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

如果返回的 JSON 数据仅包含这两个键值对,则将类型声明为[String:String]避免类型转换。

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

在任何情况下,您都必须将更新变量的代码放入do - catch表达式的“good”分支。

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

回答by Yogesh Chauhan

Tested and Working for Swift 5.0.

经过测试并适用于 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!"
}

回答by user3441734

why not use Swift's native types directly?

为什么不直接使用 Swift 的原生类型?

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

回答by Vivek

Swift 4

斯威夫特 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
    }
}