简体   繁体   English

无法快速从 JSON 中正确提取数据

[英]Unable to extract data properly from JSON in swift

I have a this kind of json object in my response after parsing json string to object将 json 字符串解析为对象后,我的响应中有这种 json 对象

[
    "requestId": 1, 
    "response": {
        code = SUCCESS;
    }, 
    "messageId": ACTION_COMPLETE
]

I am trying to extract requestId using我正在尝试使用提取requestId

responseMsg["requestId"] as! Int

I am getting this error我收到此错误

Could not cast value of type 'NSTaggedPointerString' (0x21877a910) to 'NSNumber' (0x218788588).无法将“NSTaggedPointerString”(0x21877a910)类型的值转换为“NSNumber”(0x218788588)。

I tried it changing to Int(responseMsg["requestId"] as! String)!我尝试将其更改为Int(responseMsg["requestId"] as! String)! This thing is working for positive numbers but not for negative numbers probably bcz when requestId = -2 it throws me an error这东西适用于正数,但不适用于负数,可能 bcz 当requestId = -2它会抛出一个错误

Could not cast value of type '__NSCFNumber' (0x21877a000) to 'NSString' (0x218788290).无法将“__NSCFNumber”(0x21877a000)类型的值转换为“NSString”(0x218788290)。

I tried with different other solution too but did not work.我也尝试过其他不同的解决方案,但没有奏效。

For parsing the JSON data , its better use Codable instead of manually parsing everything.对于解析JSON 数据,最好使用Codable而不是手动解析所有内容。

For JSON format ,对于JSON 格式

{
    "requestId": 1,
    "response": {
        "code":"SUCCESS"
    },
    "messageId": "ACTION_COMPLETE"
}

Create Models like,创建模型,例如,

struct Root: Decodable {
    let requestId: String?
    let messageId: String
    let response: Response

    enum CodingKeys: String, CodingKey {
        case requestId, messageId, response
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        if let id = try? values.decode(Int.self, forKey: .requestId) {
            requestId = String(id)
        } else if let id = try? values.decode(String.self, forKey: .requestId) {
            requestId = id
        } else {
            requestId = nil
        }
        messageId = try values.decode(String.self, forKey: .messageId)
        response = try values.decode(Response.self, forKey: .response)
    }
}

Now, parse the JSON data using,现在,使用解析JSON 数据

do {
    let root = try JSONDecoder().decode(Root.self, from: data)
    print(root.requestId) //access requestId like this....
} catch {
    print(error)
}

Try尝试

Int(String(describing: responseMsg["requestId"]))!

This ensures any data is converted to string first and then to int这确保任何数据首先转换为字符串,然后转换为 int

This error message这个错误信息

Could not cast value of type 'NSTaggedPointerString' (0x21877a910) to 'NSNumber' (0x218788588).

tells us that the JSON request id is being parsed as a string.告诉我们 JSON 请求 id 被解析为字符串。 NSTaggedPointerString is a special internal type used by the ObjC runtime to represent strings. NSTaggedPointerString是 ObjC 运行时用来表示字符串的特殊内部类型。

Try this:试试这个:

let requestId = responseMsg["requestId"] as! String
print("request id: \(requestId)") // Prints a string

Note, it may print something that looks like a number, but it isn't one.请注意,它可能会打印一些看起来像数字的东西,但它不是一个。

The JSON you are parsing probably looks like您正在解析的 JSON 可能看起来像

{
    "requestId": "1", 
    "response": {
        "code" = "SUCCESS"
    }, 
    "messageId": "ACTION_COMPLETE"
}

Note the 1 in quotes.注意引号中的1

Swift 5斯威夫特 5

String interpolation is what worked for me!字符串插值对我有用! (casting it first to String didn't work as I had other values for which the json decoder actually did its job and cast them directly to a number) (首先将其转换为String不起作用,因为我有其他值,json 解码器实际上已完成其工作并将它们直接转换为数字)

if let responseMsg_any = responseMsg["requestId"], 
   let responseMsg_int = Int("\(responseMsg_any)") {
   //..
}

Warning:警告:

This solution allows any Type to become a String and be checked for a Int value.此解决方案允许任何Type成为String并检查Int值。 Only use this if you're not concerned about the value's Type prior to interpolation.仅当您不关心插值之前值的Type时才使用此选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM