json 解析不正确

Posted

技术标签:

【中文标题】json 解析不正确【英文标题】:json not parsing properly 【发布时间】:2019-01-08 17:50:00 【问题描述】:

所以我尝试解析一个 json 文件,当我按照语法解析它时,它给了我一个错误,无法将字符串更改为字典数组,但是当我解决问题时,它会生成 nil。谁能给个意见

func jsonFour() 
    let string = "[\"address\": 7023000630,\"reportStatus\": \"Retrieved\",\"currentLocation\": \"latitude\": 29.8529, \"longitude\": 73.99332,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" , \"address\": 7290098339, \"reportStatus\": \"Retrieved\", \"currentLocation\": \"latitude\": 21.628569, \"longitude\": 72.996956,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\"   ]"

    let data = string.data(using: .utf8)!
    do 
        if let jsonArray = try JSONSerialization.jsonObject(with: data, options : JSONSerialization.ReadingOptions.mutableContainers) as? [[ String : Any ]]
        
            print(jsonArray) // use the json here
            let address = jsonArray["address"] as! [[String:Any]]
            if let timestamp = address["timestamp"] as? [String]print(timestamp)
         else 
            print("bad json")
        
     catch let error as NSError 
        print(error)
    


当我从"String : Any" 中删除双括号时,它运行良好,但除了nil 之外没有给出任何值。

当我以这种方式继续时,它会跳过 if 语句,只打印 "bad json"

我在这里做错了什么?

【问题讨论】:

【参考方案1】:

既然有Codable,我强烈建议你使用它而不是JSONSerialization

所以首先声明你的结构与你的 JSON 结构相匹配

struct Model: Codable 
    var address: Int
    var reportStatus: String
    var currentLocation: Location


struct Location: Codable 
    var latitude, longitude: Double
    var timestamp: String

现在只需使用 JSONDecoder 解码您的 JSON

do 
    let data = string.data(using: .utf8)!
    let models = try JSONDecoder().decode([Model].self, from: data)
 catch 
    print(error)

...现在modelsModel 对象的数组,您可以使用它。

【讨论】:

【参考方案2】:

在你的代码中,sn-p jsonArray 是一个array,并且数组不能下标[[String: Any]] 类型的值,所以你应该像这样解析,

func jsonFour()
    let string = "[\"address\": 7023000630,\"reportStatus\": \"Retrieved\",\"currentLocation\": \"latitude\": 29.8529, \"longitude\": 73.99332,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" , \"address\": 7290098339, \"reportStatus\": \"Retrieved\", \"currentLocation\": \"latitude\": 21.628569, \"longitude\": 72.996956,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" ]"

    let data = string.data(using: .utf8)!
    do 
        if let jsonArray = try JSONSerialization.jsonObject(with: data, options : JSONSerialization.ReadingOptions.mutableContainers) as? [[String: Any]]
        
            print(jsonArray) // print the json here
            for jsonObj in jsonArray 
                if let dict = jsonObj as? [String: Any] 
                    if let address = dict["address"] 
                        print(address)
                    
                    if let location = dict["currentLocation"] as? [String: Any], let timeStamp = location["timestamp"]  
                        print(timeStamp)
                    
                
            
         else 
            print("bad json")
        
     catch let error as NSError 
        print(error)
    

【讨论】:

【参考方案3】:

当然,您应该为此使用Codable,但您的代码要运行使用

let string = "[\"address\": 7023000630,\"reportStatus\": \"Retrieved\",\"currentLocation\": \"latitude\": 29.8529, \"longitude\": 73.99332,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\" , \"address\": 7290098339, \"reportStatus\": \"Retrieved\", \"currentLocation\": \"latitude\": 21.628569, \"longitude\": 72.996956,\"timestamp\": \"2019-01-07T16:35:25.079+05:30\"   ]"

let data = string.data(using: .utf8)!

do 
    if let jsonArray = try JSONSerialization.jsonObject(with: data) as? [[ String : Any ]]
    
        jsonArray.forEach 

            if  let add = $0["address"] as? Int  , let currentLocation = $0["currentLocation"] as? [String:Any], let timestamp = currentLocation["timestamp"] as? String
            
                print("address is : ", add ,"timestamp is : " , timestamp)
            
        

     else 
        print("bad json")
    
 catch  
    print(error)


你明显的问题就在这里

let address = jsonArray["address"] as! [[String:Any]]

jsonArray 是一个不能用["address"] 下标的数组

【讨论】:

【参考方案4】:

数组是一个列表。它可以包含多个项目。您必须使用循环来迭代数组(例如在您的 previous question 中)

address 的值为 Int(无双引号)。

timestamp 的值是 String,并且在数组中键 currentLocation 的字典中

let data = Data(string.utf8)
do 
    if let jsonArray = try JSONSerialization.jsonObject(with: data) as? [[String : Any]]
    
        print(jsonArray) // use the json here
        for item in array 
           let address = item["address"] as! Int
           let currentLocation = item["currentLocation"] as! [String:Any]
           let timestamp = currentLocation["timestamp"] as! String
           print(timestamp)
        
     else 
        print("bad json")
    
 catch 
    print(error)

切勿在 Swift 中使用 .mutableContainers。没有意义。

【讨论】:

以上是关于json 解析不正确的主要内容,如果未能解决你的问题,请参考以下文章

jQuery 数据表解析 json 不正确

Node.js/ Express POST 请求正文被解析为不正确的 JSON

AFNetworking iOS JSON 解析仅在黎巴嫩不正确

Flutter DistanceMatrix JSON 无法正确解析

解析嵌套的 JSONArray 并以 Recyclerview 正确的方式显示它

正确解析 Json 输出