无法投类型的值“NSTaggedPointerString”到“的NSNumber”

问题描述 投票:65回答:5

我有一个雨燕结构是这样的。

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

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

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

当我尝试分配totalfup的财产totalData的价值,我得到这个错误。

无法投类型的值“NSTaggedPointerString”到“的NSNumber”

任何人都知道这是为什么?我试图改变物业类型float然后整个结构来上课,但问题仍然存在。

ios swift double nsjsonserialization
5个回答
99
投票

错误的原因是jsonDict["totalfup"]是一个字符串(NSTaggedPointerStringNSString的子类),所以你应该字符串转换为双。

请确保,捕获异常和强制拆开包装前检查的类型!

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

为了安全起见,使用if let

if let totalfup = (dict["totalfup"] as? NSString)?.doubleValue {
  // here, totalfup is a Double
}
else {
  // dict["totalfup"] isn't a String
}

16
投票

我认为这可以帮助您

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

4
投票

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

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

在任何情况下,你必须把代码更新变量进入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)")
        }
    }
}

-1
投票

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

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

-2
投票

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
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.