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.

5
  • 1
    show the code you tried, which giving error Commented Apr 9, 2018 at 7:11
  • Do not forget to add the code which you tried , so that we can help Commented Apr 9, 2018 at 7:12
  • 1
    @RatulSharker just added it :) Commented Apr 9, 2018 at 7:12
  • @AbhirajsinhThakore just posted it :) Commented Apr 9, 2018 at 7:13
  • You should consider using the Codable protocol that has made it extremely simple to parse encode/decode JSON. Commented Apr 9, 2018 at 7:13

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

Please see my updated answer. Decodable is much more convenient
Okay! Awesome! Thank you so so so much for the help!
Can you please give me an example if i want to post for example the name and description?
post something and get the response
This is a new question Apart from that there are many different ways to post something, your request is too vague.
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
    }
} 

1 Comment

Yes true! Thank you so much for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.