The code below is a json parser example. I used the quick type website to build my structs for reading in the json. All that code works but I am having an issue with looping thru the data read. I am trying to read this is a view, so I can not use a for statement. I am having issues learning how to use the ForEach Statement to loop on the contacts in this json data and print the firstName, lastName for each contact.
This is the Code
let data1JSON = """
[
{
"data": {
"viewer": {
"__typename": "Member",
"id": 123,
"firstName": "d",
"lastName": "a",
"emailAddress": "w"
},
"league": {
"id": 1111,
"name": "a",
"slug": "b",
"isMine": true,
"logo": "g",
"homePageUrl": "bA",
"facebookUrl": "www.facebook.com/B",
"phone": "1",
"contacts": [
{
"id": 12,
"firstName": "",
"lastName": "d",
"phone": null,
"__typename": "Contact"
},
{
"id": 10,
"firstName": "",
"lastName": "c",
"phone": null,
"__typename": "Contact"
}
],
"__typename": "League"
}
}
}
]
"""
// MARK: - ApaResultElement
struct ApaResultElement: Codable {
let data: DataClass
}
// MARK: - DataClass
struct DataClass: Codable {
let viewer: Viewer
let league: League
}
// MARK: - League
struct League: Codable {
let id: Int
let name, slug: String
let isMine: Bool
let logo: String
let homePageURL, facebookURL, phone: String
let contacts: [Viewer]
let typename: String
enum CodingKeys: String, CodingKey {
case id, name, slug, isMine, logo
case homePageURL = "homePageUrl"
case facebookURL = "facebookUrl"
case phone, contacts
case typename = "__typename"
}
}
// MARK: - Viewer
struct Viewer: Codable {
let id: Int
let firstName, lastName: String
let phone: JSONNull?
let typename: String
let emailAddress: String?
enum CodingKeys: String, CodingKey {
case id, firstName, lastName, phone
case typename = "__typename"
case emailAddress
}
}
typealias ApaResult = [ApaResultElement]
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
let decoder = JSONDecoder()
let leagueView = data1JSON.data(using: .utf8)!
do {
try decoder.decode([ApaResultElement].self, from: leagueView)
print("success")
}
catch {
print("Error found => \(error)")
}
let d1 = try decoder.decode([ApaResultElement].self, from: leagueView)
// This is where I need help to loop the json to extract all the data
// I see that I need to loop on each array stuct to do that.
I have looked for a good tutorial on ForEach, but none of the sites I found help me look on this JSON Data.
I am new to swift and the autocomplete feature, so any tips using Apple Developer Documentation or the Code Complete would also be appreciated.
Thanks
I'm not sure I understand your problem, but let's try.
You have an array:
let d1 = try decoder.decode([ApaResultElement].self, from: leagueView)
Do you get a valid result (what about print it ?).
I assume it's correct.
Then you can loop:
for element in d1 {. // This is an ApaResultElement
let elementData = element.data // This is a DataClass
let viewer = elementData.viewer
let league = elementData.league
// Continue to extract what you need.
}