HomeiOS Developmentios - JSON to SwiftData Decode of JSON Ends in Error at...

ios – JSON to SwiftData Decode of JSON Ends in Error at ObservationRegistrar


I am scuffling with a SwiftUI app for iOS17 and SwiftData. I’m trying to obtain information from a JSON supply and retailer the info in SwiftData. I can obtain and decode the info right into a Swift struct, however haven’t been in a position to take action with a SwiftData @Mannequin class. The code beneath contains each the struct and SwiftData procedures. The SwiftData lessons are SDTopLevel and SDFuelStation, the structs are TopLevelX and FuelStationX. The button in FuelStationListView calls both
loadDataSD or loadDataX. The URL is right and accommodates a demo key.

struct FuelStationListView: View {

    @Setting(.modelContext) var context
    @Question(kind: SDFuelStation.stationName) var fuelStations: [SDFuelStation]

    @State personal var sdTopLevel: SDTopLevel?
    @State personal var topLevel: TopLevelX?

    var physique: some View {
        NavigationStack {
            Button("Fetch") {
                Activity {
                    await loadDataX()//works
                    //await loadDataSD()//doesn't work
                }
            }
            Checklist {
                ForEach(fuelStations) { fuelStation in
                    Textual content(fuelStation.stationName)
                }
            }
            .navigationTitle("Gas Stations")
        }//nav
    }//physique

    func loadDataSD() async {

        guard let url = URL(string: "https://developer.nrel.gov/api/alt-fuel-stations/v1.json?api_key=DEMO_KEY&restrict=10") else {
            print("Invalid URL")
            return
        }

        do {
            let (information, response) = strive await URLSession.shared.information(from: url)
            guard (response as? HTTPURLResponse)?.statusCode == 200 else {
                print(response)
                return
            }
        
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let decodedResponse = strive decoder.decode(SDTopLevel.self, from: information)
            print(decodedResponse)
        
            sdTopLevel = decodedResponse
            print("sdTopLevel.fuelStations.depend is (sdTopLevel?.fuelStations.depend ?? 1000)")

        } catch {
            print("Invalid Knowledge")
        }

    }//load information

    func loadDataX() async {

        guard let url = URL(string: "https://developer.nrel.gov/api/alt-fuel-stations/v1.json?api_key=DEMO_KEY&restrict=10") else {
            print("Invalid URL")
            return
        }

        do {
        
            let (information, response) = strive await URLSession.shared.information(from: url)
            guard (response as? HTTPURLResponse)?.statusCode == 200 else {
                print(response)
                return
            }
        
            let decoder = JSONDecoder()
            decoder.keyDecodingStrategy = .convertFromSnakeCase
            let decodedResponse = strive decoder.decode(TopLevelX.self, from: information)
        
            self.topLevel = decodedResponse
            print("topLevel.fuelStations.depend is (topLevel?.fuelStations.depend ?? 0)")

            for station in decodedResponse.fuelStations {
                print(station.stationName)
            }
        
            self.topLevel = nil

        } catch {
            print("Invalid Knowledge")
        }

    }//load information

}//struct gas Station listing view

And the info:

@Mannequin
class SDFuelStation: Codable {

    enum CodingKeys: CodingKey {
        case id, metropolis, stationName, streetAddress
    }//enum

    public var id: Int

    var stationName: String = ""
    var streetAddress: String = ""
    var metropolis: String = ""

    public init(stationName: String, streetAddress: String, metropolis: String) {
        self.id = 0
        self.stationName = stationName
        self.streetAddress = streetAddress
        self.metropolis = metropolis
    }

    required public init(from decoder: Decoder) throws {
        let container = strive decoder.container(keyedBy: CodingKeys.self)
        id = strive container.decode(Int.self, forKey: .id)
        stationName = strive container.decode(String.self, forKey: .stationName)
        streetAddress = strive container.decode(String.self, forKey: .streetAddress)
        metropolis = strive container.decode(String.self, forKey: .metropolis)
    }//required init

    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
    
        strive container.encode(id, forKey: .id)
        strive container.encode(stationName, forKey: .stationName)
        strive container.encode(streetAddress, forKey: .streetAddress)
        strive container.encode(metropolis, forKey: .metropolis)
    }

}//class

struct TopLevelX: Codable {
    let fuelStations: [FuelStationX]
}

struct FuelStationX: Codable {

    let id: Int

    var stationName: String = ""
    var streetAddress: String = ""
    var metropolis: String = ""

}//struct

The error is within the Mannequin code in a getter:

enter image description here

Any steerage can be appreciated. Xcode 15.0 iOS 17

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments