I am having a lot of trouble trying to decode this JSON with Swift 4.
{
"Items": [
{
"id": 1525680450507,
"animal": "bee",
"type": "insect",
"diet": [
"a",
"b",
"c"
]
}
],
"Count": 1,
"ScannedCount": 5
}
Here's where I try to decode
let decoder = JSONDecoder()
let data = try decoder.decode([Animal].self, from: data)
I have created a struct like this
struct Animal: Codable {
var id: Int
var animal: String
var type: String
var diet: [String]
}
let decoder = JSONDecoder()
let data = try decoder.decode(ItemsResponse.self, from: data)
This doesn't work. I get an error that says
"Expected to decode Array<\Any> but found a dictionary instead."
So I thought maybe I needed something like this
struct ItemsResponse: Codable {
var Items: [Animal]
var Count: Int
var ScannedCount: Int
}
But this doesn't work either. Now I get
"Expected to decode Array<\Any> but found a string/data instead."
How do I make a struct that will decode this JSON?
let data = try decoder.decode([Animal].self, from: data)
[Animal].self is not correct you can use it like this :
struct DataJson: Codable {
let items: [Item]
let count, scannedCount: Int
enum CodingKeys: String, CodingKey {
case items = "Items"
case count = "Count"
case scannedCount = "ScannedCount"
}
}
struct Item: Codable {
let id: Int
let animal, type: String
let diet: [String]
}
// MARK: Convenience initializers
extension DataJson {
init(data: Data) throws {
self = try JSONDecoder().decode(DataJson.self, from: data)
}
func jsonData() throws -> Data {
return try JSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
extension Item {
init(data: Data) throws {
self = try JSONDecoder().decode(Item.self, from: data)
}
func jsonData() throws -> Data {
return try JSONEncoder().encode(self)
}
func jsonString(encoding: String.Encoding = .utf8) throws -> String? {
return String(data: try self.jsonData(), encoding: encoding)
}
}
Try this:
import Foundation
let json = """
{
"Items": [
{
"id": 1525680450507,
"animal": "bee",
"type": "insect",
"diet": [
"a",
"b",
"c"
]
}
],
"Count": 1,
"ScannedCount": 5
}
"""
struct Animal: Codable {
var id: Int
var animal: String
var type: String
var diet: [String]
}
struct ItemsResponse: Codable {
var Items: [Animal]
var Count: Int
var ScannedCount: Int
}
let data = try! JSONDecoder().decode(ItemsResponse.self, from: json.data(using: .utf8)!)
Of course, you should properly handle the possible failures (i.e. don't do try!, and don't force-unwrapp the json.data()! part)
But the code above works and hopefully answers your question.
Related
currently I'm trying to decode JSON with a nested Array. The nested array can have some random numbers of the object inside it. I try to decode it but turns out it return an errors
CodingKeys(stringValue: "itenaries", intValue: nil),
debugDescription : "Expected to decode Array<Any> but found a dictionary
Sample JSON data
{
"itenaries": {
"days":
[
[
{
"itenary_id":0,
"itenary_location_name":"Batu Caves Temple"
}
],
[
{
"itenary_id":0,
"itenary_location_name":"KL Tower "
},
{
"itenary_id":1,
"itenary_location_name":"KL Forest Eco Park"
}
]
]
}
}
My Struct
struct Itenaries : Codable {
let itenaries : [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
Decoding Implementation
let decoder = JSONDecoder()
let itenary = try decoder.decode(Itenaries.self, from: fileData)
print(itenary.itenaries[0][0].itenary_id)
Where do you decode the days key? That's the problem. You need an intermediate struct
struct Root : Decodable {
let itenaries : Itenary
}
struct Itenary : Decodable {
let days : [[Days]]
}
...
let result = try decoder.decode(Root.self, from: fileData)
print(result.iternaries.days[0][0].itenary_id)
i'd probably do something like
struct Name:Codable {
var itenaries:itenaries
}
struct itenaries:Codable {
var days = [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
so basically according the structure of your Json file
Root struct -> itenaries -> [[days]]
hope you understand :)
[Edited]
you can try these.
I'm getting correct result using this approach
Result
struct MainResponse : Codable {
let itenaries : Itenaries
}
struct Itenaries : Codable {
let days : [[Days]]
}
struct Days : Codable {
let itenary_id : Int
let itenary_location_name : String
}
if let path = Bundle.main.path(forResource: "nested_array", ofType: "json") {
do {
let responseData = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let decoder = JSONDecoder()
let mainResponse = try decoder.decode(MainResponse.self, from: responseData)
print(mainResponse.itenaries.days[0][0].itenary_id)
print(mainResponse.itenaries.days[0][0].itenary_location_name)
print(mainResponse.itenaries.days[1][0].itenary_id)
print(mainResponse.itenaries.days[1][0].itenary_location_name)
print(mainResponse.itenaries.days[1][1].itenary_id)
print(mainResponse.itenaries.days[1][1].itenary_location_name)
// output
// 0
// Batu Caves Temple
// 0
// KL Tower
// 1
// KL Forest Eco Park
} catch let error {
print(error.localizedDescription)
}
}
Your model is not correct, replace it by the following:
struct ItenariesResponse: Codable {
let itenaries: Itenaries
}
struct Itenaries: Codable {
let days: [[Day]]
}
struct Day: Codable {
let itenaryID: Int
let itenaryLocationName: String
enum CodingKeys: String, CodingKey {
case itenaryID = "itenary_id"
case itenaryLocationName = "itenary_location_name"
}
}
Then replace the type you decode like that:
let itenary = try decoder.decode(ItenariesResponse.self, from: fileData)
I am new to Swift. I want to fetch some json data from the server using the url. I tried many other solutions but they didn't work. I want to print the duration key (text and value) from the array and then print it in console.
The Json data is attached below
{
"status": "OK",
"rows": [
{
"elements": [
{
"duration": {
"text": "3 hours 49 mins",
"value": 13725
},
"distance": {
"text": "225 mi",
"value": 361715
},
"status": "OK"
}
]
}
],
"origin_addresses": [
"Washington, DC, USA"
],
"destination_addresses": [
"New York, NY, USA"
]
}
Attached Code
func getdatajson1(){
if let url = URL(string: "http://www.json-generator.com/api/json/get/bQywstyfkO?indent=2") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let res = try JSONDecoder().decode(Root.self, from: data)
print(res.rows)
} catch let error {
print(error)
}
}
}.resume()
}
}
struct Root: Codable {
let rows: [Root2]
}
struct Root2: Codable {
let elements: [Root3]
}
struct Root3: Codable {
let elements: [node]
}
struct node: Codable {
let duration : [valuesarray]
}
struct valuesarray: Codable {
let text : String
let value : Int
}
The duration is an Object and not an Array, also change your names and you can use this:
struct Root: Decodable {
let rows: [Rows]
}
struct Rows: Decodable {
let elements: [Elements]
}
struct Elements: Decodable {
let duration, distance: LocationValues
}
struct LocationValues: Decodable {
let text: String
let value: Int
}
func getdatajson1(){
if let url = URL(string: "http://www.json-generator.com/api/json/get/bQywstyfkO?indent=2") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let res = try JSONDecoder().decode(Root.self, from: data)
if let row = res.rows.first, let elements = row.elements.first {
print(elements.duration.text) //This is how you can get the text value
print(elements.distance.text) //This will print the distance
}
} catch let error {
print(error)
}
}
}.resume()
}
}
Replace your codable struct with the below
class Result: Codable {
var status:String?
var rows:[Row]?
var origin_addresses:[String]?
var destination_addresses:[String]?
}
class Row: Codable {
var elements:[Element]?
}
class Element: Codable {
var status:String?
var duration:Duration?
var distance:Distance?
}
class Duration: Codable {
var text:String?
var value:Int?
}
class Distance: Codable {
var text:String?
var value:Int?
}
You should update your node model like below
struct node: Codable {
let duration : valuesarray
let distance : valuesarray
let status : String
}
And you can access your duration data from API response like below
if let rows = res.rows, rows.count > 0 {
//Access the element objects from rows
let arrElements = rows[0].elements, arrElements.count > 0 {
if let durationData = arrElements[0].duration { //get your duration object
print(durationData.text)
print(durationData.value)
}
}
}
try this:
and a hint: go to https://app.quicktype.io/ -> here you can paste your json and you will get your datastructs for free! ;)
func getdatajson1(){
if let url = URL(string: "http://www.json-generator.com/api/json/get/bQywstyfkO?indent=2") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let res = try JSONDecoder().decode(Welcome.self, from: data)
print(res.rows)
} catch let error {
print(error)
}
}
}.resume()
}
}
getdatajson1()
struct Welcome: Codable {
let status: String
let rows: [Row]
let originAddresses, destinationAddresses: [String]
enum CodingKeys: String, CodingKey {
case status, rows
case originAddresses = "origin_addresses"
case destinationAddresses = "destination_addresses"
}
}
// MARK: - Row
struct Row: Codable {
let elements: [Element]
}
// MARK: - Element
struct Element: Codable {
let duration, distance: Distance
let status: String
}
// MARK: - Distance
struct Distance: Codable {
let text: String
let value: Int
}
i have a local json string and i am trying to parse it but when i try to do so, i am constantly getting an error. I have also seen this error in nested dictionary but couldnt find an error.
Below is the json string
let jsonNestedString = "{\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\" : 38}, \"reweries\":[\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"]}"
i am doing this process via Codable and below is the struct i have created for the same
struct PagedBreweries:Codable{
struct Meta:Codable{
let page : Int
let total_pages:Int
let per_page:Int
let total_records: Int
enum CodingKeys: String, CodingKey{
case page
case total_pages
case per_page
case total_records
}
}
struct Brewery :Codable{
let id:Int
let name:String
}
let meta:Meta
let breweries :[Brewery]
}
then this data is parsed to a function as below
func jsonNested(){
let jsonData = jsonNestedString.data(using: .utf8)
let decoder = JSONDecoder()
let data = try! decoder.decode(PagedBreweries.Meta.self, from: jsonData!)
print(data)
}
and when i try to build, the error i get is present in try! decoder.decode
command
and the error is
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "page", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"page\", intValue: nil) (\"page\").", underlyingError: nil))
Could any one provide a solution?
Thanks in advance
Correct json
{
"meta": {
"page": 1,
"total_pages": 4,
"per_page": 10,
"total_records": 38
},
"reweries": [{
"id": 1234,
"name": "saintArnold"
},
{
"id": 52892,
"name": "buffalo bayou"
}
]
}
struct Root: Codable {
let meta: Meta
let reweries: [Rewery]
}
struct Meta: Codable {
let page, totalPages, perPage, totalRecords: Int
enum CodingKeys: String, CodingKey { // snake case may be used
case age = "page"
case totalPages = "total_pages"
case perPage = "per_page"
case totalRecords = "total_records"
}
}
struct Rewery: Codable {
let id: Int
let name: String
}
let jsonNestedString = """
{\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\":38}, \"reweries\":[{\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"}]}
"""
// or
let jsonNestedString = """
{
"meta": {
"page": 1,
"total_pages": 4,
"per_page": 10,
"total_records": 38
},
"reweries": [{
"id": 1234,
"name": "saintArnold"
},
{
"id": 52892,
"name": "buffalo bayou"
}
]
}
"""
do {
let jsonData = jsonNestedString.data(using: .utf8)
let decoder = JSONDecoder()
let data = try decoder.decode(Root.self, from: jsonData!)
print(data)
} catch {
print(error)
}
The JSON is corrupt and you are decoding the wrong root object.
This is the correct JSON being decoded with your structs and conforming to the Swift naming convention
let jsonNestedString = """
{"meta":{"page":1,"total_pages":4,"per_page":10,"total_records" : 38}, "breweries":[{"id":1234,"name":"saintArnold"},{"id":52892,"name":"buffalo bayou"}]}
"""
struct PagedBreweries : Codable {
struct Meta : Codable {
let page : Int
let totalPages:Int
let perPage:Int
let totalRecords: Int
}
struct Brewery : Codable {
let id:Int
let name:String
}
let meta:Meta
let breweries :[Brewery]
}
func jsonNested(){
let jsonData = Data(jsonNestedString.utf8)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let data = try! decoder.decode(PagedBreweries.self, from: jsonData)
print(data)
}
jsonNested()
// Printed result:
// PagedBreweries(meta: __lldb_expr_1.PagedBreweries.Meta(page: 1, totalPages: 4, perPage: 10, totalRecords: 38), breweries: [__lldb_expr_1.PagedBreweries.Brewery(id: 1234, name: "saintArnold"), __lldb_expr_1.PagedBreweries.Brewery(id: 52892, name: "buffalo bayou")])
This is my JSON response:
[
[
{
"id": 22,
"request_id": "rqst5c12fc9e856ae1.06631647",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Apache Load/Ubuntu",
}
],
[
{
"id": 24,
"request_id": "rqst5c130cae6f7609.41056231",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Load",
}
]
]
This JSON structure got an array inside of an array, the object of the inner array is what I am trying to parse. Here is the my mapper:
struct JobResponseDataObject: Mappable {
init?(map: Map) {
}
var id: Int?
var requestId: String?
var businessName: String?
var businessEmail: String?
mutating func mapping(map: Map) {
id <- map["id"]
requestId <- map["request_id"]
businessName <- map["business_name"]
businessEmail <- map["business_email"]
}
}
I have tried create another mapper struct to hold the array of objects [JobResponseDataObject] and use Alamofire's responseArray with it, but it didn't work. I have also tried prefixing my json id with 0. but that didn't work too. Please help
Thank
So here's the deal...Codable is a pretty cool protocol from Apple to handle parsing JSON responses from APIs. What you're getting back is an array of arrays, so your stuff's gonna be look like this:
[[ResponseObject]]
So anyway, you'd make a struct of your object, like so:
struct ResponseObject: Codable {
let id: Int?
let requestId: String?
let businessName: String?
let businessEmail: String?
let title: String?
}
You'll note I changed the key name a bit (instead of request_id, I used requestId). The reason is JSONDecoder has a property called keyDecodingStrategy which presents an enum of canned decoding strategies you can select from. You'd do convertFromSnakeCase.
Here's code you can dump into a playground to tinker with. Basically, declare your struct, match it up to whatever the keys are in your JSON, declare a decoder, feed it a decoding strategy, and then decode it.
Here's how you could do an Alamofire call:
private let backgroundThread = DispatchQueue(label: "background",
qos: .userInitiated,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
Alamofire.request(url).responseJSON(queue: backgroundThread) { (response) in
guard response.result.error == nil else {
print("💥KABOOM!💥")
return
}
if let data = response.data {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
print(parsedResponse)
} catch {
print(error.localizedDescription)
}
}
}
Here's code you can chuck in a playground.
import UIKit
let json = """
[
[
{
"id": 22,
"request_id": "rqst5c12fc9e856ae1.06631647",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Apache Load/Ubuntu",
}
],
[
{
"id": 24,
"request_id": "rqst5c130cae6f7609.41056231",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Load",
}
]
]
"""
struct ResponseObject: Codable {
let id: Int?
let requestId: String?
let businessName: String?
let businessEmail: String?
let title: String?
}
if let data = json.data(using: .utf8) {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
print(parsedResponse)
} catch {
print(error.localizedDescription)
}
}
You should use this JobResponseDataObject struct as [[JobResponseDataObject]] instead of [JobResponseDataObject] - where you are making a property using this struct in your parent struct or class.
You can use Codable here for mapping the JSON response, The JobResponseDataObject struct should look like,
struct JobResponseDataObject: Codable {
var id: Int?
var requestId: String?
var businessName: String?
var businessEmail: String?
var title: String?
private enum CodingKeys: String, CodingKey {
case id = "id"
case requestId = "request_id"
case businessName = "business_name"
case businessEmail = "business_email"
case title = "title"
}
}
let json = JSON(responseJSON: jsonData)
do {
if let value = try? json.rawData(){
let response = try! JSONDecoder().decode([[JobResponseDataObject]].self, from: value)
}
} catch {
print(error.localizedDescription)
}
I'm trying to parse data i've received from the server so as to display it into a UIPicker view. but it's too complex for me to parse and get it displayed into UIPIcker View. Whats the best way i can parse the following data into and make it ready for a UIPickerView.
This is the session trying to parse the information from the server
let url = NSURL(string: "http://dummy.com/api")!
let request = URLRequest(url: url as URL)
URLSession.shared.dataTask(with: request) { data, response, error in
if error == nil {
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
guard let parseJSON = json else{
print("Error While Parsing")
return
}
print(parseJSON)
let responseDic = parseJSON["response"] as? NSDictionary
let utilityCode = responseDic?["utility_code"] as? String
if utilityCode == "AFRICELL" {
let africellPackages = responseDic?["packages"] as! NSArray
print(africellPackages)
}
}catch{
return
}
}
}.resume()
The following data is the response from the server when the GET request is made.
{
"status": "OK",
"response": [
{
"utility_code": "AIRTEL",
"packages": [
{
"package_id": 33,
"package_name": "Daily 10MB",
"package_code": "6000",
"package_price": 300
},
{
"package_id": 34,
"package_name": "Daily 20MB",
"package_code": "6002",
"package_price": 500
},
{
"package_id": 65,
"package_name": "Weekly Roaming 200MB",
"package_code": "6030",
"package_price": 100000
}
]
},
{
"utility_code": "AFRICELL",
"packages": [
{
"package_id": 68,
"package_name": "Daily 10 MB",
"package_code": "5000",
"package_price": 290
}
]
},
{
"utility_code": "SMART",
"packages": [
{
"package_id": 69,
"package_name": "Daily 50 MB",
"package_code": "8000",
"package_price": 500
}
]
},
{
"utility_code": "SMILE",
"packages": [
{
"package_id": 70,
"package_name": "Smile 1GB",
"package_code": "7006",
"package_price": 32000
}
]
}
]
}
Cheers and thanks for the help!
All examples below are provided without error checking for brevity. For production code, you should handle errors properly.
Swift 3 without any external framework
Most of the work to decode JSON manually involves defining the data model:
struct JSONResponse {
var status: String
var response: [Utility]
init(jsonDict: [String: AnyObject]) {
self.status = jsonDict["status"] as! String
self.response = [Utility]()
let response = jsonDict["response"] as! [AnyObject]
for r in response.map({ $0 as! [String: AnyObject] }) {
let utility = Utility(jsonDict: r)
self.response.append(utility)
}
}
}
struct Utility {
var code: String
var packages: [Package]
init(jsonDict: [String: AnyObject]) {
self.code = jsonDict["utility_code"] as! String
self.packages = [Package]()
let packages = jsonDict["packages"] as! [AnyObject]
for p in packages.map({ $0 as! [String: AnyObject] }) {
let package = Package(jsonDict: p)
self.packages.append(package)
}
}
}
struct Package {
var id: Int
var name: String
var code: String
var price: Int
init(jsonDict: [String: AnyObject]) {
self.id = jsonDict["package_id"] as! Int
self.name = jsonDict["package_name"] as! String
self.code = jsonDict["package_code"] as! String
self.price = jsonDict["package_price"] as! Int
}
}
And how to use it:
let jsonDict = try! JSONSerialization.jsonObject(with: data) as! [String: AnyObject]
let jsonResponse = JSONResponse(jsonDict: jsonDict)
let utilities = jsonResponse.response
print(utilities)
Swift 3 with ObjectMapper
Decoding JSON is it of a pain in standard Swift. You need an external JSON framework like ObjectMapper to ease the pain in mapping between the JSON data and your data model. Install ObjectMapper from CocoaPod or Carthage.
First, define your data model in a separate file:
import ObjectMapper
struct JSONResponse : Mappable {
var status: String?
var response: [Utility]?
init?(map: Map) { }
mutating func mapping(map: Map) {
self.status <- map["status"]
self.response <- map["response"]
}
}
struct Utility : Mappable {
var code: String?
var packages: [Package]?
init?(map: Map) { }
mutating func mapping(map: Map) {
self.code <- map["code"]
self.packages <- map["packages"]
}
}
struct Package : Mappable {
var id: Int?
var name: String?
var code: String?
var price: Int?
init?(map: Map) { }
mutating func mapping(map: Map) {
self.id <- map["package_id"]
self.name <- map["package_name"]
self.code <- map["package_code"]
self.price <- map["package_price"]
}
}
Then you can use it to map JSON to your object like this:
// data is what your get in the dataTask's completion block
let jsonString = String(data: data, encoding: .utf8)!
if let jsonResponse = JSONResponse(JSONString: jsonString),
let utilities = jsonResponse.response {
print(utilities)
}
Everything has to be declared optional because you don't know if the value will be in the JSON string or not.
In Swift 4
Things get a lot simpler in Swift 4 with the new Encodable and Decodable protocols. Both combined to form the Encodable protocol (yes, protocol composition is a new thing in Swift 4). You no longer need ObjectMapper in Swift 4.
You still need to define your data model first:
struct JSONResponse : Codable {
var status: String
var response: [Utility]
}
struct Utility : Codable {
var code: String
var packages: [Package]
private enum CodingKeys: String, CodingKey {
case code = "utility_code"
case packages
}
}
struct Package : Codable {
var id: Int
var name: String
var code: String
var price: Int
private enum CodingKeys: String, CodingKey {
case id = "package_id"
case name = "package_name"
case code = "package_code"
case price = "package_price"
}
}
And here's how you use the new JSONDecoder struct in Swift 4:
let jsonRepsonse = try! JSONDecoder().decode(JSONResponse.self, from: data)
let utilities = jsonRepsonse.response
print(utilities)
So what's going on here?
Both ObjectMapper and Codable map the values in JSON to your data model.
In ObjectMapper, you have to explicitly list which property maps to which value in JSON in a function named mapping(map:):
mutating func mapping(map: Map) {
self.id <- map["package_id"]
self.name <- map["package_name"]
self.code <- map["package_code"]
self.price <- map["package_price"]
}
<- is the "mapping operator" defined by ObjectMapper (it's not in the Standard Library).
With Swift 4's Codable, the compiler automates a lot of things for you, which makes it appear magical and confusing at first. Essentially you define your mappings in an enum called CodingKeys:
struct JSONResponse : Codable {
var status: String
var response: [Utility]
// Define your JSON mappings here
private enum CodingKeys: String, CodingKey {
case status = "status"
case response = "response"
}
}
struct Package : Codable {
var id: Int
var name: String
var code: String
var price: Int
// Define your JSON mappings here
private enum CodingKeys: String, CodingKey {
case id = "package_id"
case name = "package_name"
case code = "package_code"
case price = "package_price"
}
}
If your JSON keys are the same as your property name, like in the JSONResponse struct, you don't have to define the explicit value for each case and you can simply write:
struct JSONResponse : Codable {
var status: String
var response: [Utility]
private enum CodingKeys: String, CodingKey {
case status // no explicit value here
case response
}
}
Better yet, since every JSON key is the same as your property name, you can omit the CodingKeys enum all together and let the compiler handle that for you:
// All you need to do is to conform it to Codable
// CodingKeys is generated automatically
struct JSONResponse : Codable {
var status: String
var response: [Utility]
}
To learn more about Codable, watch the What's new in Foundation session from WWDC 2017.