How do I parse this nested JSON using Codable with Swift? - ios

I am trying to parse this JSON using Codable:
{
"users": [
{
"id": 1,
"name": "Allen Carslake",
"userName": "acarslake0",
"profileImage": "https://source.unsplash.com/random/400x400",
"createdDate": "2019-07-08T00:00:00.000+0000"
},
{
"id": 2,
"name": "Revkah Antuk",
"userName": "rantuk1",
"profileImage": "https://source.unsplash.com/random/400x400",
"createdDate": "2019-07-05T00:00:00.000+0000"
},
{
"id": 3,
"name": "Mirna Saffrin",
"userName": "msaffrin2",
"profileImage": "https://source.unsplash.com/random/400x400",
"createdDate": "2019-05-19T00:00:00.000+0000"
},
{
"id": 4,
"name": "Haily Eilers",
"userName": "heilers3",
"profileImage": "https://source.unsplash.com/random/400x400",
"createdDate": "2019-06-28T00:00:00.000+0000"
},
{
"id": 5,
"name": "Oralie Polkinhorn",
"userName": "opolkinhorn4",
"profileImage": "https://source.unsplash.com/random/400x400",
"createdDate": "2019-06-04T00:00:00.000+0000"
}
]
}
I am keeping the URL private on here but it is returning JSON above. So far this is my code:
import UIKit
struct User: Codable {
let id: Int
let name: String
let userName: String
let profileImage: String
let createdDate: String
}
struct Users: Codable {
let users: String
}
let url = URL(string: "")!
URLSession.shared.dataTask(with: url) { data, _, _ in
if let data = data {
let users = try? JSONDecoder().decode([User].self, from: data)
print(users)
}
}.resume()
I need to be able to access the User properties but I think the nesting is making it difficult for me. Any help is awesome!! Thank you!!

First of all: Catch always the DecodingError and print it. It tells you exactly what's wrong.
The error occurs because you are ignoring the root object Users. Your code works if you decode(Users.self.
My suggestions:
Decode createdDate as Date adding a appropriate date decoding strategy.
Decode profileImage as URL (for free).
Handle all errors.
struct Root : Decodable { // `Users` and `User` is too confusing
let users: [User]
}
struct User : Decodable {
let id: Int
let name: String
let userName: String
let profileImage: URL
let createdDate: Date
}
URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error { print(error); return }
do {
let decoder = JSONDecoder()
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let result = try decoder.decode(Root.self, from: data!)
for user in result.users {
print(user.userName, user.id, user.createdDate)
}
} catch {
print(error)
}
}.resume()

The root of the json is a dictionary not an array you can write a root class but it will be useless , so you need
URLSession.shared.dataTask(with: url) { data, _, _ in
do {
if let data = data {
let res = try JSONSerialization.jsonObject(with: data) as! [String:Any]
let usersData = try JSONSerialization.data(withJSONObject: res["users"])
let users = try JSONDecoder().decode([User].self, from: usersData)
print(users)
}
}
catch {
print(error)
}
}.resume()

Your Users struct (I renamed it to UsersResponse) should contain a users property of type [User]. Then you can do the following:
struct UsersResponse: Codable {
let users: [User]
}
URLSession.shared.dataTask(with: url) { data, _, _ in
guard let data = data else { return }
if let users = try? JSONDecoder().decode(Users.self, from: data).users {
users.forEach { user in
print("A user called \(user.name) with an id of \(user.id).")
}
}
}.resume()

Please try the below code. This is working for me.
Model Class:
struct UsersResponse: Codable {
let users: [User]
}
struct User: Codable {
let id: Int
let name: String
let userName: String
let profileImage: String?
let createdDate: String
}
Network class:
public enum EndPoints: String {
case prod = "ProdURL"
case test = "testURL"
}
public enum Result<T> {
case success(T)
case failure(Error)
}
final public class Networking: NSObject {
// MARK: - Private functions
private static func getData(url: URL,
completion: #escaping (Data?, URLResponse?, Error?) -> ()) {
URLSession.shared.dataTask(with: url, completionHandler: completion).resume()
}
/// fetchUsersResponse function will fetch the User Response and returns
/// Result<UsersResponse> as completion handler
public static func fetchUsersResponse(shouldFail: Bool = false, completion: #escaping (Result<UsersResponse>) -> Void) {
var urlString: String?
if shouldFail {
urlString = EndPoints.test.rawValue
} else {
urlString = EndPoints.prod.rawValue
}
guard let mainUrlString = urlString, let url = URL(string: mainUrlString) else { return }
Networking.getData(url: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
guard let data = data, error == nil else { return }
do {
let decoder = JSONDecoder()
//decoder.dateDecodingStrategy = .millisecondsSince1970
decoder.dateDecodingStrategy = .formatted(setDateFormat())
let json = try decoder.decode(UsersResponse.self, from: data)
completion(.success(json))
} catch let error {
completion(.failure(error))
}
}
}
func setDateFormat() -> DateFormatter {
let dateFormat = DateFormatter()
dateFormat.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
return dateFormat
}

Related

JSON Decode Function From File Versus Web

SwiftUI is supposed to simplify things- I am bit frustrated as I have been working on the URLSession+JSONDecoder for weeks, I really need some help!
I have a function to load JSON data from a file in Swift and it works as expected. I copy/pasted the function and updated it to get the data via an API, however I receive a compile time error: "Unexpected non-void return value in void function". Is my approach wrong to use a function for JSON over the web?
JSON response:
{
"T":"CSU",
"v":468303,
"vw":1.2838,
"o":1.31,
"c":1.24,
"h":1.38,
"l":1.2001,
"t":1607374800000,
"n":994
}
struct Root2: Codable {
var T: String
var v: Double
var vw: Double
var o: String
var c: String
var h: Double
var l: Double
var t: Double
}
This file-based function works as expected:
let symbolData: [Root2] = load("symbolData.json")
func load<T: Decodable>(_ filename: String) -> T {
let data: Data
guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}
do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
}
do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
}
}
For the web version, I receive compile time error: "Unexpected non-void return value in void function".
Line: return try decoder.decode(T.self, from: data)
func loadURL<T: Decodable>() -> T {
guard let url = URL(string: """)
else {
fatalError("Invalid URL in main bundle.")
}
let request = URLRequest(url: url)
URLSession.shared.dataTask(with: request) { data, response, error in
do {
if let data = data {
let stringData = String(decoding: data, as: UTF8.self)
print("1 Fetched: \(url)")
print("2 Response: \(stringData)")
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
}
}
catch {
fatalError("Couldn't parse as :\n\(error)")
}
}.resume()
}
Working version after Leo's help!
class Manager: ObservableObject {
#Published var symbols: [Symbol] = []
func loadURL<T: Decodable>(using decoder: JSONDecoder = .msSince1970, completion: #escaping ((T?, Error?) -> Void)) {
let url = URL(string: """)!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
print("ops")
completion(nil, error)
return
}
print("1 Fetched: \(url)")
print("2 Response:", String(data: data, encoding: .utf8) ?? "")
_ = Data("""
[
{
"open": {
"price": 124.02,
"time": 1657105851499
},
"close": {
"price": 124.96,
"time": 1618647822184
},
"high": 124.64,
"low": 124.65,
"volume": 75665274,
"symbol": "AAPL"
}
]
""".utf8)
do {
completion(try decoder.decode(T.self, from: data), nil)
//completion(try decoder.decode(T.self, from: tempDataForTesting), nil)
} catch {
completion(nil, error)
}
}.resume()
}
}
extension JSONDecoder {
static let msSince1970: JSONDecoder = {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
return decoder
}()
}
You can't wait for an asynchronous task to finish and return the result. What you need is a completion handler. You would need also to explicitly set the resulting type if you don't pass the resulting type to your decode method and you need to call resume to start your url session data task:
import SwiftUI
struct ContentView: View {
#ObservedObject var manager = Manager()
#State var string: String = "Hello, world!"
var body: some View {
Text(manager.symbol)
.padding()
.onAppear {
manager.load(symbol: manager.symbol) { (symbols: [Symbol]?, error: Error?) in
guard let symbols = symbols else {
print("error:", error ?? "")
string = "JSON could not be parsed"
return
}
for symbol in symbols {
print(symbol.open.price)
print(symbol.open.time)
print(symbol.close.price)
print(symbol.close.time)
print(symbol.high)
print(symbol.low)
print(symbol.volume)
print(symbol.symbol)
DispatchQueue.main.async {
manager.symbols = symbols
}
}
string = "JSON was successufly parsed"
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class Manager: ObservableObject {
#Published var symbols: [Symbol] = []
#Published var symbol: String = "IBM"
func load<T: Decodable>(symbol: String, using decoder: JSONDecoder = .msSince1970, completion: #escaping ((T?, Error?) -> Void)) {
guard let url = URLComponents(symbol: symbol).url else {
completion(nil, URL.Error.invalidURL)
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data else {
print("ops")
completion(nil, error)
return
}
print("1 Fetched: \(url)")
print("2 Symbol: \(symbol)")
print("3 Response:", String(data: data, encoding: .utf8) ?? "")
do {
completion(try decoder.decode(T.self, from: data), nil)
} catch {
completion(nil, error)
}
}.resume()
}
}
struct Symbol: Codable {
let open, close: Price
let high, low: Double
let volume: Int
let symbol: String
}
struct Price: Codable {
let price: Double
let time: Date
}
extension JSONDecoder {
static let msSince1970: JSONDecoder = {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .millisecondsSince1970
return decoder
}()
}
extension URLComponents {
init(scheme: String = "https",
host: String = "sandbox.iexapis.com",
path: String = "/stable/stock/market/ohlc",
symbol: String,
token: String = "YOUR_API_TOKEN") {
self.init()
self.scheme = scheme
self.host = host
self.path = path
self.queryItems = [URLQueryItem(name: "symbols", value: symbol),
URLQueryItem(name: "token", value: token)]
}
}
extension URL {
enum Error: String, Swift.Error {
case invalidURL = "Invalid URL"
}
}
This will print
1 Fetched: https://sandbox.iexapis.com/stable/stock/market/ohlc?symbols=IBM&token=YOUR_API_TOKEN
2 Symbol: IBM
3 Response: [{"open":{"price":128.9,"time":1636600302693},"close":{"price":131.44,"time":1662259300134},"high":132.517,"low":130.074,"volume":3403359,"symbol":"IBM"}]
128.9
2021-11-11 03:11:42 +0000
131.44
2022-09-04 02:41:40 +0000
132.517
130.074
3403359
IBM

Swift - parsing wikidata with urlsession and json decoder not working

I'm trying to build a engine that will take a few pieces of data and parse them through a wikidata query...there are two url session tasks here is my code, but for some reason I can't get the functions to perform the networking to execute...what am I missing?
struct BDayWikiDataManager {
func fetchBDayDataFromWikipedia(numMonth: String, numDay: String) -> (String, String, String) {
var personLabelCode = "no value"
var occupationLabelCode = "no value"
var dob = "no value"
var personName = "no value"
var occupationName = "no value"
let firstURL = "https://query.wikidata.org/sparql?query=SELECT%20distinct%20%3Fperson%20%3FpersonLabel%20%3Fdob%20%3Foccupation%20%3FoccupationLabel%20%3Fawards%20%3FawardsLabel%0AWHERE%0A{%0A%20%20%3Fperson%20wdt%3AP31%20wd%3AQ5%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP27%20wd%3AQ30%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP569%20%3Fdob%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP166%20%3Fawards%3B%0A%20%20%20%20%20%20%20%20%20%20wdt%3AP106%20%3Foccupation.%0A%20%20OPTIONAL%20{%3Fperson%20wdt%3AP166%20%3Fawards}%0A%20%20FILTER(DAY(%3Fdob)%20%3D%20\(numDay)).%0A%20%20FILTER(MONTH(%3Fdob)%20%3D%20\(numMonth)).%0A%20%20FILTER(YEAR(%3Fdob)%20%3E%3D%201940).%0A%20%20FILTER%20(%3Foccupation%20in%20(%20wd%3AQ33999%2C%20wd%3AQ639669%2C%20wd%3AQ2066131%2C%20wd%3AQ947873%2C%20wd%3AQ15265344%20)%20)%0A%20%20SERVICE%20wikibase%3Alabel%20{%20bd%3AserviceParam%20wikibase%3Alanguage%20%22[AUTO_LANGUAGE]%22.%20}%20%0A}%0ALIMIT%2050&format=json"
performRequestFirstURL(with: firstURL) { (data, error) in
if error != nil {
print(error as Any)
}
personLabelCode = data!.personLabel
print(personLabelCode)
occupationLabelCode = data!.occupationLabel
dob = data!.dob
}
print(personLabelCode)
let secondUrl = "https://www.wikidata.org/w/api.php?action=wbgetentities&ids=\(personLabelCode)|\(occupationLabelCode)&format=json&props=labels&languages=en"
let _ = performRequestSecondURL(with: secondUrl, personLabel: personLabelCode, occupationLabel: occupationLabelCode) { (data, error) in
if error != nil {
fatalError("performRequestSecondURL failed, error = \(String(describing: error))")
}
personName = data!.personName
occupationName = data!.occupationName
}
return (personName, occupationName, dob)
}
func performRequestFirstURL(with urlString: String, userCompletionHandler: #escaping (FirstURLData?, Error?) -> Void) {
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
if let data = data {
let jsonDecoder = JSONDecoder()
do {
let parsedJSON = try jsonDecoder.decode(FirstURLIncomingData.self, from: data)
print(parsedJSON)
let numberOfBindings = parsedJSON.results.bindings.count
let randomBindingNumber = Int.random(in: 0...(numberOfBindings - 1))
let dob = parsedJSON.results.bindings[randomBindingNumber].dob.value
let personLabel = parsedJSON.results.bindings[randomBindingNumber].personLabel.value
let occupationLabel = parsedJSON.results.bindings[randomBindingNumber].occupationLabel.value
let finalData = FirstURLData(dob: dob, personLabel: personLabel, occupationLabel: occupationLabel)
userCompletionHandler(finalData, nil)
} catch {
print(error)
userCompletionHandler(nil,error)
}
}
})
.resume()
}
}
func performRequestSecondURL(with urlString: String, personLabel: String, occupationLabel: String, userCompletionHandler: #escaping (SecondURLData?, Error?) -> Void) {
if let url = URL(string: urlString) {
URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
if let data = data {
let jsonDecoder = JSONDecoder()
do {
let parsedJSON = try jsonDecoder.decode(SecondURLIncomingData.self, from: data)
print(parsedJSON)
let name = parsedJSON.entities[personLabel]?.labels.en.value
let occupation = parsedJSON.entities[occupationLabel]?.labels.en.value
let finalData = SecondURLData(personName: name!, occupationName: occupation!)
userCompletionHandler(finalData, nil)
} catch {
print(error)
userCompletionHandler(nil,error)
}
}
})
.resume()
}
}
}
//MARK: - incoming data model - first url
struct FirstURLIncomingData: Codable {
let results: Results
}
struct Results: Codable {
let bindings: [Bindings]
}
struct Bindings: Codable {
let dob: DOB
let personLabel: PersonLabel
let occupationLabel: OccupationLabel
}
struct DOB: Codable {
let value: String
}
struct PersonLabel: Codable {
let value: String
}
struct OccupationLabel: Codable {
let value: String
}
//MARK: - incoming data model - second url
struct SecondURLIncomingData: Decodable {
let entities: [String : Locator]
}
struct Locator: Decodable {
let labels: Labels
}
struct Labels: Decodable {
let en: EN
}
struct EN: Decodable {
let value: String
}
//MARK: - model of data for both urls
struct FirstURLData: Decodable {
let dob: String
let personLabel: String
let occupationLabel: String
}
struct SecondURLData {
let personName: String
let occupationName: String
}
let manager = BDayWikiDataManager()
let data = manager.fetchBDayDataFromWikipedia(numMonth: "8", numDay: "13")
print(data) //prints "no data" for everything, which means the values didnt update
Worth noting: when I go to the url's manually, I get json responses in my browser, so I know the url's are correct...

How do I map API?

I'm new to swift language and trying to work on the API below..
https://api.foursquare.com/v2/venues/search?ll=40.7484,-73.9857&oauth_token=NPKYZ3WZ1VYMNAZ2FLX1WLECAWSMUVOQZOIDBN53F3LVZBPQ&v=20180616
I'm trying to parse the data and then serialise, however I'm not able to map the data.
struct Venue: Codable {
let id: String
let name: String
let contact: Location
}
struct Location: Codable {
let address: String
let postalCode: String
}
class DataService {
private init() {}
static let shared = DataService()
func getdata() {
guard let url = URL(string: "https://api.foursquare.com/v2/venues/search?ll=40.7484,-73.9857&oauth_token=NPKYZ3WZ1VYMNAZ2FLX1WLECAWSMUVOQZOIDBN53F3LVZBPQ&v=20180616") else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
do {
guard let venues = try? JSONDecoder().decode([Venue].self, from: data) else { return }
print(venues[0].id)
} catch let jsonError {
print(jsonError)
}
}
}
task.resume()
}
}
I need to work on venues array ( mainly "id", "name", "location" ( "address", "postalCode" ))
I'm trying to use the codable and decodable, how do I get the the results, please help.
This is a very common mistake.
You ignore the root object (the dictionary containing the meta and response keys). And the venues are in the dictionary for key response, a sub-dictionary of the root object
struct Root : Decodable {
let response : Response
}
struct Response : Decodable {
let venues : [Venue]
}
struct Venue: Decodable {
let id: String
let name: String
let location : Location
}
struct Location: Decodable { // both struct members must be optional
let address: String?
let postalCode: String?
}
And – as Joakim already said in the comments – never ignore Decoding errors. Decoding errors are very descriptive. They contain the specific error message as well as the CodingPath of the error.
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let data = data {
do {
let result = try JSONDecoder().decode(Root.self, from: data)
result.response.venues.forEach{print($0.id)}
} catch {
print(error)
}
}
}
task.resume()

Error trying to parse JSON using URLSession in swift

I'm trying to parse a test JSON from a http adress, but I get an error saying that
"No value associated with key CodingKeys(stringValue: \"name\", intValue: nil)
The JSON looks like this. It has been validated, so it should work ok:
{
"work": [
{
"name": "Jocke",
"job": "Developer",
"date": "1985-12-30T00:00:00+0000",
"best_book": {
"id": 33245,
"title": "DiscWorld",
"author": {
"id": 345,
"name": "Terry Prattchet"
}
}
},
{
"name": "Bob",
"job": "Construction worker",
"date": "2010-01-30T00:00:00+0000",
"best_book": {
"id": 375802,
"title": "Ender's Game (Ender's Saga, #1)",
"author": {
"id": 589,
"name": "Orson Scott Card"
}
}
}
]
}
The code looks like this:
struct People: Codable {
let name: String
let job: String
enum OuterKey: String, CodingKey {
case work = "work"
}
enum codingKeys: String, CodingKey {
case name = "name"
case job = "job"
}
init(decoder: Decoder) throws {
let outerContainer = try decoder.container(keyedBy: OuterKey.self)
let innerContainer = try outerContainer.nestedContainer(keyedBy: CodingKeys.self, forKey: .work)
self.name = try innerContainer.decode(String.self, forKey: .name)
self.job = try innerContainer.decode(String.self, forKey: .job)
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
guard let url = URL(string: "https://api.myjson.com/bins/fe2eo") else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data else { return }
do {
let jsonDecoder = JSONDecoder()
jsonDecoder.keyDecodingStrategy = .convertFromSnakeCase
let decodedJson = try! jsonDecoder.decode([People].self, from: data)
}
}.resume()
}
}
I'm just trying to grasp the first two keys as of now, just to see if it works. But it doesn't even get past name.
Your api returns
[{"firstName":"Jocke","job":"developer"},{"firstName":"Anna","job":"construction"},{"firstName":"Peter","job":"pilot"}]
do {
let jsonDecoder = JSONDecoder()
let decodedJson = try jsonDecoder.decode([People].self, from: data)
}
catch {
print(error)
}
struct People: Codable {
let firstName, job: String
}
just try this
struct Work:Codeable {
let work:[People]
}
struct People: Codable {
let name: String
let job: String
}
do {
let jsonDecoder = JSONDecoder()
let decodedJson = try jsonDecoder.decode(Work.self, from: data)
}
catch {
print(error)
}
if you have same name as json keys you don't need to use codingkeys

Value of type '[Root]' has no member 'commit'. How can i decode JSON root array

I am trying to parse JSON using codable. I am able to decode it but it is in a root array and i am unable to print each value on by it self. the compiler is complaining saying Value of type '[Root]' has no member 'commit'. How can i change this to print the values. Below is the JSON
[
{
"sha": "3f4227ec2894bb354b145deff9dbc1adc6b6d6f2",
"node_id": "MDY6Q29tbWl0NDQ4Mzg5NDk6M2Y0MjI3ZWMyODk0YmIzNTRiMTQ1ZGVmZjlkYmMxYWRjNmI2ZDZmMg==",
"commit": {
"author": {
"name": "Slava Pestov",
"email": "sviatoslav.pestov#gmail.com",
"date": "2018-08-12T08:09:22Z"
}
}
},
{
"sha": "3f4227ec2894bb354b145deff9dbc1adc6b6d6f2",
"node_id": "MDY6Q29tbWl0NDQ4Mzg5NDk6M2Y0MjI3ZWMyODk0YmIzNTRiMTQ1ZGVmZjlkYmMxYWRjNmI2ZDZmMg==",
"commit": {
"author": {
"name": "Slava Pestov",
"email": "sviatoslav.pestov#gmail.com",
"date": "2018-08-12T08:09:22Z"
}
}
}
]
I decode it here
struct Root: Decodable {
let commit: Author
}
struct Author: Decodable {
let author: People
}
struct People: Decodable {
let name: String?
let date: String?
let email: String?
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
getCommits()
}
func getCommits() {
let urlString = "https://api.github.com/repos/apple/swift/commits"
guard let url = URL(string: urlString) else {
print("Couldn't fetch JSON")
return
}
let session = URLSession.shared
let dataTask = session.dataTask(with: url) { (data, response, error) in
guard data != nil && error == nil else {
print(data ?? "")
return
}
do {
let decoder = JSONDecoder()
let result = try decoder.decode([Root].self, from: data!)
print(result.commit)
print(result.commit.author.name)
} catch let decodeError {
print("Failed to decode json:", decodeError)
}
}
dataTask.resume()
}
}
And here is my output in the console. I would like to be able to print only the name, date and email.
[Gihhub.Commits(commit: Gihhub.Author(author: Gihhub.People(name: Optional("Slava Pestov"), date: Optional("2018-08-12T08:09:22Z"), email: Optional("sviatoslav.pestov#gmail.com")))), Gihhub.Commits(commit: Gihhub.Author(author: Gihhub.People(name: Optional("Slava Pestov"), date: Optional("2018-08-12T03:47:22Z"), email: Optional("spestov#apple.com")))), Gihhub.Commits(commit: Gihhub.Author(author: Gihhub.People(name: Optional("Slava Pestov"), date: Optional("2018-08-12T03:47:08Z"), email: Optional("spestov#apple.com"))))]
result is an array you need
result.forEach {
print($0.commit.author.name)
print($0.commit.author.date)
print($0.commit.author.email)
}

Resources