このような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"]
が文字列(NSTaggedPointerString
は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
値を返すためです。
返されたJSONデータにこれらの2つのキーと値のペアのみが含まれる場合、型を[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)")
}
}
}