I have been trying to decode a JSON from a PHP that I have and then displaying the results as Text. I am getting either one of two errors with everything I have tried. The first issue would be "Expected to decode Array but found a dictionary instead." I changed some things up in the struct I had for this and resolved that issue. However, I then got an issue with having no data from the call.
Here is the relevant portion of the code that I have for this. I am currently using the secondtabview for the testing and the firsttabview as a control.
struct CallData: Decodable, Identifiable{
private enum CodingKeys: String, CodingKey { case records}
let id = UUID()
let gdata: [Record]
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let records = try container.decode([String:[String]].self, forKey: .records)
gdata = records.map(Record.init).sorted{$0.iD < $1.iD}
}
}
struct Record {
let iD: String
let data: [String]
}
class ContentModel: ObservableObject {
@Published var records = [Record]()
init() {
getData()
}
func getData(){
let url = URL(string: "https://not.the.real.php?route=Green")
if let url = url {
var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10)
request.httpMethod = "GET"
URLSession.shared.dataTask(with: request){ (data, response, error) in
if error == nil {
do {
let decoder = JSONDecoder()
let result = try decoder.decode(CallData.self, from: data!)
print(result)
DispatchQueue.main.async {
self.records = result.gdata
}
} catch {
print(error)
}
}
}.resume()
}
}
}
struct FirstTabView: View{
@Namespace var mapScopeRed
var body: some View {
VStack{
ScrollView{
Text("Red \nred")
}
Map(scope: mapScopeRed){
Marker("Here", coordinate: .You)
}.mapStyle(.hybrid(elevation: .realistic))
MapUserLocationButton(scope: mapScopeRed).tint(.red)
}.mapScope(mapScopeRed)
}
}
struct SecondTabView: View{
@Namespace var mapScope
@State var gmodel = [CallData]()
var body: some View {
VStack{
List(gmodel) { route in
ScrollView{
let ginfo = "\(route.gdata)"
Text(ginfo)
}
}
Map(scope: mapScope){
Marker("Here", coordinate: .Youtoo)
}.mapStyle(.hybrid(elevation: .realistic))
MapUserLocationButton(scope: mapScope).tint(.red)
}.mapScope(mapScope)
}
}
I will also include what the structure of the JSON results from the web results of the php.
{"records":[{"ID":"354","route":"Green","stop_name":"StopOne","lat":"-11.11","lng":"11.11","stop_order":"1","stop_time":"5","NewOrder":"1"},{"ID":"355","route":"Green","stop_name":"StopTwo","lat":"-11.11","lng":"11.11","stop_order":"2","stop_time":"60","NewOrder":"2"},{"ID":"356","route":"Green","stop_name":"StopThree","lat":"-11.11","lng":"11.11","stop_order":"3","stop_time":"30","NewOrder":"3"},{"ID":"357","route":"Green","stop_name":"StopFour","lat":"-11.11","lng":"11.11","stop_order":"4","stop_time":"42","NewOrder":"4"},{"ID":"358","route":"Green","stop_name":"StopFive","lat":"-11.11","lng":"11.11","stop_order":"5","stop_time":"54","NewOrder":"5"},{"ID":"359","route":"Green","stop_name":"StopSix","lat":"-11.11","lng":"11.11","stop_order":"6","stop_time":"95","NewOrder":"6"}]}
Now as stated previously I have tried a multitude of different things I have found online, but nothing actually results in Observable data. I would like to be able to display each stop_name and corresponding stop_time within the scrollview. I'd assume my issue is with how I have the CallData and/or Record structures I have set up (Or possibly my ContentModel Class). I am completely new to swift so any advice on this or swift in general would be helpful.