This is the error I get
Invalid data: typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "Services", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "NextBus", intValue: nil), CodingKeys(stringValue: "EstimatedArrival", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))
When I try to print the estimatedArrival in the SwiftUI View as a Text() converted from the date format 2022-08-29T12:06:28+08:00
which is in "yyyy-MM-dd’T’HH:mm:ssZ" format.
However when I change to estimatedArrival: String
instead of Date
, it doesn't the error anymore.
import SwiftUI
import Foundation
// MARK: - Welcome
struct BusTimings: Codable {
let busStopCode: String
let services: [Service]
enum CodingKeys: String, CodingKey {
case busStopCode = "BusStopCode"
case services = "Services"
}
}
// MARK: - Service
struct Service: Codable {
let serviceNo, serviceOperator: String
let nextBus, nextBus2, nextBus3: NextBus
enum CodingKeys: String, CodingKey {
case serviceNo = "ServiceNo"
case serviceOperator = "Operator"
case nextBus = "NextBus"
case nextBus2 = "NextBus2"
case nextBus3 = "NextBus3"
}
}
// MARK: - NextBus
struct NextBus: Codable {
let originCode, destinationCode: String
let estimatedArrival: Date
let latitude, longitude, visitNumber, load: String
let feature, type: String
enum CodingKeys: String, CodingKey {
case originCode = "OriginCode"
case destinationCode = "DestinationCode"
case estimatedArrival = "EstimatedArrival"
case latitude = "Latitude"
case longitude = "Longitude"
case visitNumber = "VisitNumber"
case load = "Load"
case feature = "Feature"
case type = "Type"
}
}
struct StopView: View {
let item: BusStop
let dateFormatter = DateFormatter()
@State private var value = [Service]()
//@State private var busStop = [BusStop]()
//var locations = [Locations]()
var body: some View {
List(value, id: \.serviceNo) { item in
NavigationLink(destination:Text(item.serviceNo)) {
VStack(alignment: .leading) {
Text(item.serviceNo)
.font(.largeTitle)
Text(dateFormatter.string(from: item.nextBus.estimatedArrival))
// .bold()
}
}
}
.task {
await loadData()
}
.navigationTitle(item.Description)
.navigationBarTitleDisplayMode(.inline)
}
//let url = Bundle.main.url(forResource: "data", withExtension: "json")!
func loadData() async {
let busStopCode = item.BusStopCode
let accountKey = "xxx"
guard let url = URL(string: String("http://datamall2.mytransport.sg/ltaodataservice/BusArrivalv2" + "?AccountKey=" + accountKey + "&BusStopCode=" + busStopCode))
else { print("Invalid URL")
return
}
//print(dateFormatter.string(from: Date.now))
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue(accountKey, forHTTPHeaderField: "AccountKey")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
do {
let (data, _) = try await URLSession.shared.data(for: request) // <-- here
//print(String(data: data, encoding: .utf8)) // <-- here
let decodedResponse = try JSONDecoder().decode(BusTimings.self, from: data)
value = decodedResponse.services
} catch {
print("Invalid data: \(error)")
}
}
}
Thank you for reading through this! I appreciate your help!