1

I have an api which return a JSON and i want to parse this JSON and use it in my application.

I have tried the get method from this: swift JSON login REST with post and get response example

Code:

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()

}

And i got as an output: error trying to convert data to JSON..

My JSON IS:

[
  {
    "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
  }
]

Why i got error parsing the JSON?

Also, how to loop for the array and print each item?

For example:

service 1 description is: This is a description of Services 1. This is a description of Services 1 This is a description of Services 1.

service 2 description is: This is a description of Services 2. This is a description of Services 2 This is a description of Services 2.

nayem
  • 7,285
  • 1
  • 33
  • 51
Lama
  • 255
  • 3
  • 17

2 Answers2

3

Please read the JSON carefully. The root object is clearly an array ([])

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

However I recommend to use the Decodable protocol. Declare this struct outside the class

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

and decode the JSON this way

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

Side note:

The line guard let responseData = data else { will never reach the else clause. If error is nil – which has been checked already – then it's guaranteed that data has a value.

vadian
  • 274,689
  • 30
  • 353
  • 361
0

I think you're making small mistake, you have a list of todo, parsing won't give you the todo itself. It will give you the Array of todo

In 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
    }
} 
Ratul Sharker
  • 7,484
  • 4
  • 35
  • 44