swifty json parse array object - ios

how can I set an array of Images to an images variable of the Car class
my json:
{
"Description": "test comment",
"GalleryId": 5548,
"ShortCode": "rzswig",
"Images": [
{
"Id": 9742,
"Link": "https://url/Images/5548/image9742_x560.jpg"
},
{
"Id": 9749,
"Link": "https://url/Images/5548/image9749_x560.jpg"
},
{
"Id": 9746,
"Link": "https://url/Images/5548/image9746_x560.jpg"
}
]
}
my class :
class Car: Hashable {
var shortCode: String
var description: String
var galleryId: Int
var imageItems: [ImageItem]?
init(response: JSON) {
shortCode = response["ShortCode"].stringValue
description = response["Description"].stringValue
galleryId = response["GalleryId"].intValue
imageItems = response["Images"].arrayObject.map {$0} as? [ImageItem]
}
init(shortCode: String, description: String, galleryId: Int, imageItems: [ImageItem]?) {
self.description = description
self.shortCode = shortCode
self.galleryId = galleryId
self.imageItems = imageItems
}
}
struct ImageItem {
var id: Int
var link: String
}
variant:
imageItems = response["Images"].arrayObject.map {$0} as? [ImageItem]
doesn't work for me

If you want to keep using SwiftyJSON, you can add an initialiser to ImageItem that takes a JSON, just like you did with Car:
init(response: JSON) {
id = response["Id"].intValue
link = response["Link"].stringValue
}
You might also want to add the autogenerated member wise initialiser back if you want it.
Then, to initialise imageItems, do:
imageItems = response["Images"].array?.map(ImageItem.init(response:))
This whole thing would be a lot easier if you used the Codable API built in to Swift.
Just conform both Car and ImageItem to Codable:
class Car: Codable {
var shortCode: String
var description: String
var galleryId: Int
var imageItems: [ImageItem]?
enum CodingKeys: String, CodingKey {
case shortCode = "ShortCode"
case description = "Description"
case galleryId = "GalleryId"
case imageItems = "Images"
}
}
struct ImageItem: Codable {
var id: Int
var link: String
enum CodingKeys: String, CodingKey {
case id = "Id"
case link = "Link"
}
}
And then do this to deserialise the json:
let car = JSONDecoder().decode(Car.self, data: jsonData) // jsonData is of type "Data"

I think the problem is that you map it as array of Image item
imageItems = response["Images"].arrayObject.map {$0} as? ImageItem

try response["images"].arrayValue

Related

Swift Codable JSON parse error with JSONDecoder

I am trying to handle a JSON with Codable but there's a parsing error when I decode it with JSONDecoder().decode.
{
"data": [
{
"id": "90",
"symbol": "BTC",
"name": "Bitcoin",
"nameid": "bitcoin",
"rank": 1,
"price_usd": "50513.75",
"percent_change_24h": "3.03",
"percent_change_1h": "-0.50",
"percent_change_7d": "-9.91",
"price_btc": "1.00",
"market_cap_usd": "942710364520.73",
"volume24": 70745042591.75044,
"volume24a": 107034995571.4168,
"csupply": "18662452.00",
"tsupply": "18662452",
"msupply": "21000000"
},
{
"id": "80",
"symbol": "ETH",
"name": "Ethereum",
"nameid": "ethereum",
"rank": 2,
"price_usd": "4052.44",
"percent_change_24h": "10.17",
"percent_change_1h": "-0.78",
"percent_change_7d": "17.75",
"price_btc": "0.084812",
"market_cap_usd": "466734637594.73",
"volume24": 53134000887.50444,
"volume24a": 87082811090.79503,
"csupply": "115173595.00",
"tsupply": "115173595",
"msupply": ""
}
],
"info": {
"coins_num": 5949,
"time": 1621022046
}
}
The json is like above and I coded all my models like below.
class CoinModel: Codable {
var data: [Coin]?
var info: CoinInfo?
enum CodingKeys: String, CodingKey {
case data
case info
}
}
class CoinInfo: Codable {
var coinsNum: Int?
var time: TimeInterval?
enum CodingKeys: String, CodingKey {
case coinsNum = "coins_num"
case time = "time"
}
}
class Coin: Codable{
var csupply: String?
var id: String?
var marketCapUsd: String?
var msupply: Int?
var name: String?
var nameid: String?
var percentChange1h: String?
var percentChange24h: String?
var percentChange7d: String?
var priceBtc: String?
var priceUsd: String?
var rank: Int?
var symbol: String?
var tsupply: Int?
var volume24: Double?
var volume24a: Double?
enum CodingKeys: String, CodingKey {
case csupply = "csupply"
case id = "id"
case marketCapUsd = "market_cap_usd"
case msupply = "msupply"
case name = "name"
case nameid = "nameid"
case percentChange1h = "percent_change_1h"
case percentChange24h = "percent_change_24h"
case percentChange7d = "percent_change_7d"
case priceBtc = "price_btc"
case priceUsd = "price_usd"
case rank = "rank"
case symbol = "symbol"
case tsupply = "tsupply"
case volume24 = "volume24"
case volume24a = "volume24a"
}
}
And my network function work like below.
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard error == nil else {
completion(.failure(error!))
return
}
guard let data = data else {
completion(.failure(error ?? NSError()))
return
}
let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
guard let model = try? JSONDecoder().decode(CoinModel.self, from: data) else {
completion(.success([]))
return
}
completion(.success(model.data ?? []))
}.resume()
As I said before, json object is not nil and I got like below.
[({
csupply = "435032301.00";
id = 33285;
"market_cap_usd" = "435337535.24";
msupply = "";
name = "USD Coin";
nameid = "usd-coin";
"percent_change_1h" = "0.01";
"percent_change_24h" = "0.19";
"percent_change_7d" = "0.16";
"price_btc" = "0.000023";
"price_usd" = "1.00";
rank = 100;
symbol = USDC;
tsupply = 435032301;
volume24 = "11520659193.03477";
volume24a = "13684311331.83874";
}
)
, "info": {
"coins_num" = 5952;
time = 1621160044;
}]
I can handle the JSON with JSONSerialization but I could not find any reason for parse error in the JSONDecoder way. I think I did not see the problem. Thanks for any advice and helps.
Edit:
I solved it with several changes in my Codable class, I made a mistake when I describing model for id, csupply and etc.
var csupply: String?
var msupply: String?
var tsupply: String?
You have several mistakes on defining object. For example you have defined id, msupply is a integer but they are string. You have defined the volume24 and volume24a is string but they are not. You need to fix all of these probably thats why you can't parse it.
All wrong defined parameters are id, mSupply, volume24, volume24a, tSupply for coin object and for the info object you need to convert time to Int aswell.

How to use Codable encode with object inside object

Im working on a JSON payload with my object payload. but im having trouble encoding object inside object.
My Payload class was this
class ConversationPayload :BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
enum CodingKeys: String, CodingKey {
case title = "title"
case messageDict = "message"
case participants = "participants"
case type = "type"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
if title != nil {
try container.encode(title, forKey: .title)
}
try container.encode(messageDict, forKey: .messageDict)
try container.encode(participants, forKey: .participants)
try container.encode(type, forKey: .type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
enum CodingKeys: String, CodingKey {
case body = "body"
case isVideocallInvite = "is_videocall_invite"
case attachmentsPayload = "attachment"
}
override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(body, forKey: .body)
try container.encode(isVideocallInvite, forKey: .isVideocallInvite)
if attachmentsPayload != nil {
try container.encode(attachmentsPayload, forKey: .attachmentsPayload)
}
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
}
BaseObject was this
class BaseObject:Codable{}
What i want to get in json payload was something like this
{"message": {"body": "body_string", "is_videocall_invite": 1}, "participants" : [user-id], "type" : "converstation_type","title":"title"}
anyone know whats wrong with my payload class? not that familiar yet on codable. thanks in advance.
I'm not sure what constrains you have here, but I would simplify all of this down. Keep the JSON data models as close to the JSON as you can get.
struct ConversationJsonModel: Codable {
var title: String?
var message: MessageJsonModel
var participants: [Int]
var type: String
}
struct MessageJsonModel: Codable {
var body: String
var is_videocall_invite: Int
var attachment: AttachmentJsonModel?
}
struct AttachmentJsonModel: Codable {
var photo: String
var photo_type: String // <-- assuming photo_type is the JSON member name.
}
If you need a view model or some other kind of local data model, then the two parts are separate.
class BaseObject {}
class ConversationPayload: BaseObject {
var title : String? = ""
var messageDict: MessagePayload = MessagePayload()
var participants: [Int32] = []
var type: String = ""
func makeConversationJsonModel() -> ConversationJsonModel {
ConversationJsonModel(title: title,
message: messageDict.makeMessageJsonModel(),
participants: participants.map { Int($0) },
type: type)
}
}
class MessagePayload: BaseObject {
var body : String = ""
var isVideocallInvite: Bool = false
var attachmentsPayload: MessageAttachmentPayload? = nil
func makeMessageJsonModel() -> MessageJsonModel {
MessageJsonModel(body: body,
is_videocall_invite: isVideocallInvite ? 1 : 0,
attachment: attachmentsPayload?.makeAttachmentJsonModel())
}
}
class MessageAttachmentPayload: BaseObject {
var photo : String = ""
var photoType : String = "jpg"
func makeAttachmentJsonModel() -> AttachmentJsonModel {
AttachmentJsonModel(photo: photo, photo_type: photoType)
}
}
Finally, encoding your JSON
let conversationPayload = ConversationPayload()
let json = try? JSONEncoder().encode(conversationPayload.makeConversationJsonModel())
This allows for clean separation between the JSON representation and the payload model. For example, in the JSON, is_videocall_invite is an Int (0 or 1); meanwhile, in the payload model, isVideocallInvite is a Bool.
What is the issue? I just tested your class, it has some minor issues but it does conforming to codable and it encoded without issue.
In playground:
var conversation = ConversationPayload()
var message = MessagePayload()
message.body = "message body"
message.isVideocallInvite = true
var attachment = MessageAttachmentPayload()
attachment.photo = "attachment_file"
message.attachmentsPayload = attachment
conversation.messageDict = message
conversation.title = "Title"
conversation.participants = [1, 2, 3, 4]
conversation.type = "Conversation Type"
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(conversation)
print(String(data: data, encoding: .utf8)!)
The output looks like the following:
{
"participants" : [
1,
2,
3,
4
],
"message" : {
"is_videocall_invite" : true,
"attachment" : {
"photo" : "attachment_file",
"photoType" : "jpg"
},
"body" : "message body"
},
"title" : "Title",
"type" : "Conversation Type"
}
I have added encode and CodingKey in MessageAttachmentPayload class to encode the values.
Isn't it what you were expecting?

how to write json objects one by one in to a json object in swift

I need to create an answer JSON with nested objects
I tried to use mappable but it won't solve the problem
I need to create this kind of array
{
"interactionId":"daade6b6adcd8b063a355e28bc1f1341",
"futureSurveyAnswers":[
{
"type":"imagepicker",
"qcode":"vxo20zeezo",
"values":[
{
"value":"lion"
}
]
},
{
"type":"radiogroup",
"qcode":"s4ep4s0shf",
"values":[
{
"value":"item1"
}
]
},
{
"type":"checkbox",
"qcode":"76k5cpnpki",
"values":[
{
"value":"item1"
},
{
"value":"item2"
}
]
}
],
"originalResultArray":"{\"question2\":\"item1\",\"question3\":[\"item1\",\"item2\"],\"question1\":\"lion\"}"
}
Currently probably the best solution to use is Codable protocol. There are many examples and tutorials online so please do check one or two, I am sure you will find it very simple to use.
The point is that you can encode concrete classes or structures directly to (and from) JSON. So your problem is then not in JSON itself but just structuring your classes. For instance:
class Survey {
class Answer {
enum AnswerType: String {
case imagepicker
}
class Value {
var value: String?
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
This way you can easily modify your structure as you want to. For instance:
let survey = Survey(interactionId: "0")
survey.futureSurveyAnswers.append({
let answer = Survey.Answer()
answer.qcode = "test"
return answer
}())
So to extend it to codable all you need to do is actually append Codable protocol to your class and any embedded component:
class Survey: Codable {
class Answer: Codable {
enum AnswerType: String, Codable {
case imagepicker
}
class Value: Codable {
var value: String?
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
Now you can get JSON as simple as the following:
let survey = Survey(interactionId: "0")
survey.futureSurveyAnswers.append({
let answer = Survey.Answer()
answer.values.append({
let value = Survey.Answer.Value()
value.value = "some"
return value
}())
answer.qcode = "test"
return answer
}())
let encoder = JSONEncoder()
if let jsonData = try? encoder.encode(survey) {
print("Generated data: \(jsonData)")
}
I hope this puts you in the right direction.
From comments this is what I used as a test example for JSON:
class Survey: Codable {
class Answer: Codable {
enum AnswerType: String, Codable {
case imagepicker
}
class Value: Codable {
var value: String?
init(value: String? = nil) { self.value = value }
}
var type: AnswerType = .imagepicker
var qcode: String?
var values: [Value] = [Value]()
}
let interactionId: String
var futureSurveyAnswers: [Answer] = [Answer]()
var originalResultArray: String?
init(interactionId: String) { self.interactionId = interactionId }
}
func addTestAnswer(to survey: Survey) {
let answer = Survey.Answer()
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
answer.values.append(.init(value: "Random value \(Int.random(in: 1...100))"))
survey.futureSurveyAnswers.append(answer)
}
func testRandomSurveyJSON() {
let survey = Survey(interactionId: "randomSurvey")
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
addTestAnswer(to: survey)
print("Got JSON: \(String(data: try! JSONEncoder().encode(survey), encoding: .utf8)!)")
}
And got the following result:
Got JSON: {"interactionId":"randomSurvey","futureSurveyAnswers":[{"type":"imagepicker","values":[{"value":"Random value 74"},{"value":"Random value 4"},{"value":"Random value 26"},{"value":"Random value 93"}]},{"type":"imagepicker","values":[{"value":"Random value 43"},{"value":"Random value 65"},{"value":"Random value 38"},{"value":"Random value 88"}]},{"type":"imagepicker","values":[{"value":"Random value 56"},{"value":"Random value 88"},{"value":"Random value 57"},{"value":"Random value 94"}]},{"type":"imagepicker","values":[{"value":"Random value 66"},{"value":"Random value 52"},{"value":"Random value 89"},{"value":"Random value 27"}]},{"type":"imagepicker","values":[{"value":"Random value 53"},{"value":"Random value 93"},{"value":"Random value 30"},{"value":"Random value 55"}]}]}
which seems to be correct.

How to make model class for dictionary inside array in swift?

Here is my Json:
[ {
"id": 6854,
"name": "Laundry Iron",
"images": [
{
"id": 6856,
"src": "https://abcd.com/yzx/uploads/1750.jpg",
}
],
} ]
how do we make model class for getting "images":["src": "String" ]?. I want to grab "src" I have tried doing like , but it is not working :
class ProductModel {
var title: String?
var regularPrice: Int?
var salePrice: Int?
var productDescroption: String?
var imageUrl: [ImageUrl]?
init(productJsonL: NSDictionary) {
self.title = productJsonL["name"] as? String
self.regularPrice = productJsonL["regular_price"] as? Int
self.salePrice = productJsonL["sale_price"] as? Int
self.productDescroption = productJsonL["description"] as? String
//The problem is here ........
//self.imageUrl = productJsonL["images"]![0]!["src"] as? String
self.imageUrl = ImageUrl(imageUrlJson: (productJsonL["images"]![0] as? NSDictionary)!)
}
}
class ImageUrl {
var source: String?
init(imageUrlJson: NSDictionary) {
self.source = imageUrlJson["src"] as? String
}
}
please correct me with the structure like I have done above so that i can append everything at once in an array ? Thank you in advance!!
You need Codable
struct Root: Codable {
let id: Int
let name: String
let images: [Image]
}
struct Image: Codable {
let id: Int
let src: String // or let src: URL
}
do {
let res = try JSONDecoder().decode([Root].self, from: data)
print(res)
}
catch {
print(error)
}

Parse Complex Nested Data From server

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.

Resources