0

I am trying to convert JSON data into an array but I do not really have any idea how to do it.

I get the data and save it in strings and I can also show it on display.

struct User_Hosting: Codable {
    let company_name: String
    let website: String
    let street: String
    let housenumber: String
    let zip: String
    let city: String    

    enum CodingKeys: String, CodingKey {
        case company_name = "company_name"
        case website = "website"
        case street = "street"
        case housenumber = "housenumber"
        case zip = "zip"
        case city = "city"
    }
}

And here some other codes:

let url = URL(string: "myURL.com")

        URLSession.shared.dataTask(with: url!, completionHandler: { [weak self] (data, response, error) in
            guard let data = data, error == nil else {
                print(error?.localizedDescription ?? "An error occurred")
                return
            }
            DispatchQueue.main.async {
                self?.dataSource = try! JSONDecoder().decode([User_Hosting].self, from: data)
            }
        }).resume()
    }
13
  • 1
    Why are you using CodingKeys when struct's property names and property names from server are identical Commented May 27, 2019 at 6:51
  • 1
    Add the JSON response that you're getting from API. Commented May 27, 2019 at 6:54
  • 1
    And what is your dataSource property in self?.dataSource = try! JSONDecoder().decode([User_Hosting].self, from: data)? Commented May 27, 2019 at 6:58
  • 4
    In Swift we prefer Camel Case (camelCase) over Snake Case (snake_case). So, you can use this line let decoder = JSONDecoder() decoder.decordingStrategy = .convertFromSnakeCase and then use let company_name as let companyName. Commented May 27, 2019 at 6:59
  • 2
    Don’t do try!, use a proper do {...} catch { print(error) } so you don’t miss any errors that might happen during decoding. The answer to your question might very well be in that print statement. And do the decoding before DispatchQueue.main.async Commented May 27, 2019 at 7:23

1 Answer 1

1

Your CodingKeys match the property names, so you can get rid of the enum at all

struct UserHosting: Codable {
    let companyName: String
    let website: String
    let street: String
    let housenumber: String
    let zip: String
    let city: String    
}

Since you have a some snake case keys in JSON, you can change the JSONDecoder.keyDecodingStrategy to convertFromSnakeCase, like so

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase

Above decoder will treat keys such as company_name to be assigned to companyName property of your struct.

Finally you can decode your JSON in a do-catch block, so in case of an error we will have a message as to what went wrong.

do {
    self.dataSource = try decoder.decode([UserHosting].self, from: data)
} catch {
    print("JSON Decoding Error \(error)")
}
Sign up to request clarification or add additional context in comments.

2 Comments

As have been pointed out many times before, do not use localizedDescription do print(error) instead for a much more detailed error message
@AamirRq I want to put alphabetical index on right side of a UITableview and only sort company name on it, but I do not know which array is having the data.

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.