Learn Courses My Dashboard

I have an error, how can I fix it

Hey guys! I have an error:

Cannot convert value of type '[Datum]' to expected argument type '[FlightModel]'

I am trying to parse JSON into the list. Example JSON:

{
-"pagination": {
"limit": 100,
"offset": 0,
"count": 1,
"total": 1
},
-"data": [
-{
"flight_date": "2021-07-23",
"flight_status": "scheduled",
-"departure": {
"airport": "Heathrow",
"timezone": "Europe/London",
"iata": "LHR",
"icao": "EGLL",
"terminal": "3",
"gate": "32",
"delay": 21,
"scheduled": "2021-07-23T14:30:00+00:00",
"estimated": "2021-07-23T14:30:00+00:00",
"actual": "2021-07-23T14:50:00+00:00",
"estimated_runway": "2021-07-23T14:50:00+00:00",
"actual_runway": "2021-07-23T14:50:00+00:00"
},
-"arrival": {
"airport": "Los Angeles International",
"timezone": "America/Los_Angeles",
"iata": "LAX",
"icao": "KLAX",
"terminal": "2",
"gate": null,
"baggage": null,
"delay": null,
"scheduled": "2021-07-23T17:45:00+00:00",
"estimated": "2021-07-23T17:45:00+00:00",
"actual": null,
"estimated_runway": null,
"actual_runway": null
},
-"airline": {
"name": "Virgin Atlantic",
"iata": "VS",
"icao": "VIR"
},
-"flight": {
"number": "23",
"iata": "VS23",
"icao": "VIR23",
"codeshared": null
},
-"aircraft": {
"registration": "G-VTEA",
"iata": "A35K",
"icao": "A35K",
"icao24": "4077D3"
},
-"live": {
"updated": "2021-07-23T18:36:02+00:00",
"latitude": 55.46,
"longitude": -62.68,
"altitude": 11582.4,
"direction": 265,
"speed_horizontal": 907.48,
"speed_vertical": 0,
"is_ground": false
}
}
]
}

My code:

//
//  FlightModel.swift
//  FlightTracker
//
//  Created by Harrinandhaan Sathish Kumaar Nirmala on 7/22/21.
//


import SwiftUI
import Foundation

// MARK: - FlightModel
struct FlightModel: Codable {
    let pagination: Pagination
    let data: [Datum]
}

// MARK: - Datum
struct Datum: Codable {
    let flightDate, flightStatus: String
    let departure, arrival: Arrival
    let airline: Airline
    let flight: Flight
    let aircraft: Aircraft
    let live: Live

    enum CodingKeys: String, CodingKey {
        case flightDate = "flight_date"
        case flightStatus = "flight_status"
        case departure, arrival, airline, flight, aircraft, live
    }
}

// MARK: - Aircraft
struct Aircraft: Codable {
    let registration, iata, icao, icao24: String
}

// MARK: - Airline
struct Airline: Codable {
    let name, iata, icao: String
}

// MARK: - Arrival
struct Arrival: Codable {
    let airport, timezone, iata, icao: String
    let terminal: String
    let gate: String?
    let baggage: JSONNull?
    let delay: Int?
    let scheduled, estimated: Date
    let actual, estimatedRunway, actualRunway: Date?

    enum CodingKeys: String, CodingKey {
        case airport, timezone, iata, icao, terminal, gate, baggage, delay, scheduled, estimated, actual
        case estimatedRunway = "estimated_runway"
        case actualRunway = "actual_runway"
    }
}

// MARK: - Flight
struct Flight: Codable {
    let number, iata, icao: String
    let codeshared: JSONNull?
}

// MARK: - Live
struct Live: Codable {
    let updated: Date
    let latitude, longitude, altitude: Double
    let direction: Int
    let speedHorizontal: Double
    let speedVertical: Int
    let isGround: Bool

    enum CodingKeys: String, CodingKey {
        case updated, latitude, longitude, altitude, direction
        case speedHorizontal = "speed_horizontal"
        case speedVertical = "speed_vertical"
        case isGround = "is_ground"
    }
}

// MARK: - Pagination
struct Pagination: Codable {
    let limit, offset, count, total: Int
}

// 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()
    }
}

enum FlightError: Error {
    case noDataAvailable
    case cannotProcessData
}


struct FlightRequest {
    let resourceURL: URL
    let API_KEY = "6b9732efdc097df8816983564d713c09"
    
    init(code: String) {
        let resourceString = "http://api.aviationstack.com/v1/flights?access_key=\(API_KEY)&flight_iata=\(code)"
        
        guard let resourceURL = URL(string: resourceString)
        else {
            fatalError()
        }
        self.resourceURL = resourceURL
    }
    func getFlight(completion: @escaping(Result<[FlightModel], FlightError>) -> Void) {
        let dataTask = URLSession.shared.dataTask(with: resourceURL) { data,_,_ in
            guard let jsonData = data
            else {
                completion(.failure(.noDataAvailable))
                return
            }
            do {
                let decoder = JSONDecoder()
                let flightResponse = try decoder.decode(FlightModel.self, from: jsonData)
                let flightDetails = flightResponse.data
                completion(.success(flightDetails)) //ERROR
            }
            catch {
                completion(.failure(.cannotProcessData))
            }
        }
        dataTask.resume()
    }
}

I have commented on the line with the error. Please help me!

Look at your getFlight function:

The completion handler takes a parameter of type Result<[FlightModel], FlightError>. So the type for the success case is [FlightModel].

But when you call completion with a success:

let flightDetails = flightResponse.data
completion(.success(flightDetails))

flightResponse.data is, according to your model, of type [Datum]

You need to call completion with the correct data type for its parameter.