developer tip

'NSTaggedPointerString'유형의 값을 'NSNumber'로 캐스트 할 수 없습니다.

copycodes 2020. 11. 11. 20:17
반응형

'NSTaggedPointerString'유형의 값을 'NSNumber'로 캐스트 할 수 없습니다.


이와 같은 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
    }
}

API에서 다음 JSON 응답을받습니다. 이것은 jsonDict변수 의 println입니다 .

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

의 값을 totalfup속성 에 할당하려고 totalData하면이 오류가 발생합니다.

'NSTaggedPointerString'유형의 값을 'NSNumber'로 캐스트 할 수 없습니다.

왜 그럴까요? 속성 유형을로 변경 float한 다음 전체 구조체를 클래스로 변경하려고 시도 했지만 여전히 문제가 발생합니다.


오류의 원인은 jsonDict["totalfup"]String ( NSTaggedPointerStringis a subclass of NSString)이므로 String을 Double로 변환해야합니다.

강제 풀기 전에 예외를 포착하고 유형을 확인하십시오!

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
}

나는 이것이 당신을 도울 수 있다고 생각합니다

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

실패 이유는 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.

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

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

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

참고URL : https://stackoverflow.com/questions/33299202/could-not-cast-value-of-type-nstaggedpointerstring-to-nsnumber

반응형