快速解析 JSON 并在数组中循环时出错

Posted

技术标签:

【中文标题】快速解析 JSON 并在数组中循环时出错【英文标题】:Error parsing JSON in swift and loop in array 【发布时间】:2018-04-09 07:09:28 【问题描述】:

我有一个返回 JSON 的 api,我想解析这个 JSON 并在我的应用程序中使用它。

我已经尝试过 get 方法:swift JSON login REST with post and get response example

代码:

func makeGetCall() 

    // Set up the URL request

    let todoEndpoint: String = "my link"

    guard let url = URL(string: todoEndpoint) else 

        print("Error: cannot create URL")

        return

    

    let urlRequest = URLRequest(url: url)



    // set up the session

    let config = URLSessionConfiguration.default

    let session = URLSession(configuration: config)



    // make the request

    let task = session.dataTask(with: urlRequest) 

        (data, response, error) in

        // check for any errors

        guard error == nil else 

            print("error calling GET on /public/api/services")

            print(error!)

            return

        

        // make sure we got data

        guard let responseData = data else 

            print("Error: did not receive data")

            return

        

        // parse the result as JSON, since that's what the API provides

        do 

            guard let todo = try JSONSerialization.jsonObject(with: responseData, options: [])

                as? [String: Any] else 

                    print("error trying to convert data to JSON")

                    return

            

            // now we have the todo

            // let's just print it to prove we can access it

            print("The todo is: " + todo.description)



            // the todo object is a dictionary

            // so we just access the title using the "title" key

            // so check for a title and print it if we have one

            guard let todoTitle = todo["name"] as? String else 

                print("Could not get todo title from JSON")

                return

            

            print("The title is: " + todoTitle)

         catch  

            print("error trying to convert data to JSON")

            return

        

    

    task.resume()


我得到一个输出:尝试将数据转换为 JSON 时出错..

我的 JSON 是:

[
  
    "id": 1,
    "name": "Services 1",
    "description": "This is a description of Services 1. This is a description of Services 1 This is a description of Services 1. ",
    "created_at": null,
    "updated_at": null
  ,
  
    "id": 2,
    "name": "Services 2",
    "description": "This is a description of Services 2. This is a description of Services 2 This is a description of Services 2. ",
    "created_at": null,
    "updated_at": null
  
]

为什么解析 JSON 时出错?

另外,如何循环数组并打印每个项目?

例如:

服务 1 描述是:这是服务 1 的描述。这是 服务 1 的描述 这是服务 1 的描述。

服务 2 描述是:这是服务 2 的描述。这是 服务 2 的描述 这是服务 2 的描述。

【问题讨论】:

显示你尝试过的代码,它给出了错误 不要忘记添加您尝试过的代码,以便我们提供帮助 @RatulSharker 刚刚添加了它:) @AbhirajsinhThakore 刚刚发布 :) 你应该考虑使用 Codable 协议,它使得解析编码/解码 JSON 变得非常简单。 【参考方案1】:

请仔细阅读 JSON。根对象显然是一个数组([]

guard let todos = try JSONSerialization.jsonObject(with: responseData) as? [[String: Any]] else                     
       print("error trying to convert data to JSON")
       return
  
  for todo in todos 
      print(todo["name"] as? String ?? "n/a")
  

但是我建议使用Decodable 协议。在类外声明这个结构

struct Service : Decodable 
    let id : Int
    let name, description : String
    let createdAt : String?
    let updatedAt : String?

并以这种方式解码 JSON

do 
   let decoder = JSONDecoder()
   decoder.keyDecodingStrategy = .convertFromSnakeCase
   let todos = try decoder.decode([Service].self, from: responseData)
   for todo in todos 
      print(todo.name)
   

 catch  print(error) 

旁注:

guard let responseData = data else 行永远不会到达else 子句。如果errornil——已经检查过了——那么保证data 有一个值。

【讨论】:

请看我更新的答案。 Decodable更方便 好的!惊人的!非常感谢您的帮助! 如果我想发布例如名称和描述,你能给我一个例子吗? 发布内容并获得回复 这是个新问题 除了post的方式有很多种,你的要求也太模糊了。【参考方案2】:

我认为你犯了一个小错误,你有一个todo 的列表,解析不会给你todo 本身。它会给你todoArray

在 Swift4 中:

//assume that you have the JSON String as Data
guard let data = data else 
     return


let json = try? JSONSerialization.jsonObject(with: response.data!, options: [])

if let array = json as? [[String: Any]] 
    for todo in array 
        // parse todo component

        if let name = todo["name"] as? String 
             print("Name : \(name)")
        

        // other properties parse in the same way
    
 

【讨论】:

没错!非常感谢您的帮助!

以上是关于快速解析 JSON 并在数组中循环时出错的主要内容,如果未能解决你的问题,请参考以下文章

我如何解析 Json 对象或数组?我的代码哪里出错了?

使用 JSON 响应快速调用函数时出错

json解析时出错

在 RestKit 中解析空数组时出错

处理 Json 请求时出错

使用body.json()解析来自http.get()的响应时出错