I'm tring to display in a Text view a nested part of a json content but I'm not able to do it correctly. For example I can't display properly the response of [Connector], any thoughts ?
Here is my struct :
import Foundation
import SwiftUI
// MARK: - StationDataApi
struct StationDataApi: Codable {
var summary: Summary
var results: [Result]
enum CodingKeys: String, CodingKey {
case summary = "summary"
case results = "results"
}
}
// MARK: - Result
struct Result: Codable {
var type: ResultType
var id: String
var score: Double
var dist: Double
var info: String
var poi: Poi
var address: Address
var position: GeoBias
var viewport: Viewport
var entryPoints: [EntryPoint]
var chargingPark: ChargingPark
var dataSources: DataSources?
enum CodingKeys: String, CodingKey {
case type = "type"
case id = "id"
case score = "score"
case dist = "dist"
case info = "info"
case poi = "poi"
case address = "address"
case position = "position"
case viewport = "viewport"
case entryPoints = "entryPoints"
case chargingPark = "chargingPark"
case dataSources = "dataSources"
}
}
// MARK: - Address
struct Address: Codable {
var streetName: String
var municipality: Country
var countrySubdivision: Country
var postalCode: String
var countryCode: CountryCode
var country: Country
var countryCodeIso3: CountryCodeIso3
var freeformAddress: String
var localName: Country
var streetNumber: String?
var municipalitySubdivision: String?
enum CodingKeys: String, CodingKey {
case streetName = "streetName"
case municipality = "municipality"
case countrySubdivision = "countrySubdivision"
case postalCode = "postalCode"
case countryCode = "countryCode"
case country = "country"
case countryCodeIso3 = "countryCodeISO3"
case freeformAddress = "freeformAddress"
case localName = "localName"
case streetNumber = "streetNumber"
case municipalitySubdivision = "municipalitySubdivision"
}
}
enum Country: String, Codable {
case luxembourg = "Luxembourg"
}
enum CountryCode: String, Codable {
case lu = "LU"
}
enum CountryCodeIso3: String, Codable {
case lux = "LUX"
}
// MARK: - ChargingPark
struct ChargingPark: Codable {
var connectors: [Connector]
enum CodingKeys: String, CodingKey {
case connectors = "connectors"
}
}
// MARK: - Connector
struct Connector: Codable {
var connectorType: String
var ratedPowerKw: Int
var voltageV: Int
var currentA: Int
var currentType: CurrentType
enum CodingKeys: String, CodingKey {
case connectorType = "connectorType"
case ratedPowerKw = "ratedPowerKW"
case voltageV = "voltageV"
case currentA = "currentA"
case currentType = "currentType"
}
}
enum CurrentType: String, Codable {
case ac3 = "AC3"
case dc = "DC"
}
// MARK: - DataSources
struct DataSources: Codable {
var chargingAvailability: ChargingAvailability
enum CodingKeys: String, CodingKey {
case chargingAvailability = "chargingAvailability"
}
}
// MARK: - ChargingAvailability
struct ChargingAvailability: Codable {
var id: String
enum CodingKeys: String, CodingKey {
case id = "id"
}
}
// MARK: - EntryPoint
struct EntryPoint: Codable {
var type: EntryPointType
var position: GeoBias
enum CodingKeys: String, CodingKey {
case type = "type"
case position = "position"
}
}
// MARK: - GeoBias
struct GeoBias: Codable {
var lat: Double
var lon: Double
enum CodingKeys: String, CodingKey {
case lat = "lat"
case lon = "lon"
}
}
enum EntryPointType: String, Codable {
case main = "main"
}
// MARK: - Poi
struct Poi: Codable {
var name: String
var phone: String?
var categorySet: [CategorySet]
var categories: [Query]
var classifications: [Classification]
enum CodingKeys: String, CodingKey {
case name = "name"
case phone = "phone"
case categorySet = "categorySet"
case categories = "categories"
case classifications = "classifications"
}
}
enum Query: String, Codable {
case electricVehicleStation = "electric vehicle station"
}
// MARK: - CategorySet
struct CategorySet: Codable {
var id: Int
enum CodingKeys: String, CodingKey {
case id = "id"
}
}
// MARK: - Classification
struct Classification: Codable {
var code: Code
var names: [Name]
enum CodingKeys: String, CodingKey {
case code = "code"
case names = "names"
}
}
enum Code: String, Codable {
case electricVehicleStation = "ELECTRIC_VEHICLE_STATION"
}
// MARK: - Name
struct Name: Codable {
var nameLocale: NameLocale
var name: Query
enum CodingKeys: String, CodingKey {
case nameLocale = "nameLocale"
case name = "name"
}
}
enum NameLocale: String, Codable {
case enUs = "en-US"
}
enum ResultType: String, Codable {
case poi = "POI"
}
// MARK: - Viewport
struct Viewport: Codable {
var topLeftPoint: GeoBias
var btmRightPoint: GeoBias
enum CodingKeys: String, CodingKey {
case topLeftPoint = "topLeftPoint"
case btmRightPoint = "btmRightPoint"
}
}
// MARK: - Summary
struct Summary: Codable {
var query: Query
var queryType: String
var queryTime: Int
var numResults: Int
var offset: Int
var totalResults: Int
var fuzzyLevel: Int
var geoBias: GeoBias
enum CodingKeys: String, CodingKey {
case query = "query"
case queryType = "queryType"
case queryTime = "queryTime"
case numResults = "numResults"
case offset = "offset"
case totalResults = "totalResults"
case fuzzyLevel = "fuzzyLevel"
case geoBias = "geoBias"
}
Here is an extract of the Json response :
{
"summary": {
"query": "electric vehicle station",
"queryType": "NON_NEAR",
"queryTime": 130,
"numResults": 10,
"offset": 0,
"totalResults": 232894,
"fuzzyLevel": 1,
"geoBias": {
"lat": 49.588056,
"lon": 6.104167
}
},
"results": [
{
"type": "POI",
"id": "442009000702915",
"score": 8.495806694,
"dist": 357.116545666857,
"info": "search:ev:442009000702915",
"poi": {
"name": "Chargy Luxembourg Place de Roedgen",
"phone": " 352 800 62 020",
"categorySet": [
{
"id": 7309
}
],
"categories": [
"electric vehicle station"
],
"classifications": [
{
"code": "ELECTRIC_VEHICLE_STATION",
"names": [
{
"nameLocale": "en-US",
"name": "electric vehicle station"
}
]
}
]
},
"address": {
"streetName": "Place de Roedgen",
"municipality": "Luxembourg",
"countrySubdivision": "Luxembourg",
"postalCode": "L-2432",
"countryCode": "LU",
"country": "Luxembourg",
"countryCodeISO3": "LUX",
"freeformAddress": "Place de Roedgen, Luxembourg, L-2432",
"localName": "Luxembourg"
},
"position": {
"lat": 49.59111,
"lon": 6.1057
},
"viewport": {
"topLeftPoint": {
"lat": 49.59201,
"lon": 6.10431
},
"btmRightPoint": {
"lat": 49.59021,
"lon": 6.10709
}
},
"entryPoints": [
{
"type": "main",
"position": {
"lat": 49.59104,
"lon": 6.10555
}
}
],
"chargingPark": {
"connectors": [
{
"connectorType": "IEC62196Type2Outlet",
"ratedPowerKW": 22,
"voltageV": 400,
"currentA": 32,
"currentType": "AC3"
}
]
},
"dataSources": {
"chargingAvailability": {
"id": "442009000702915"
}
}
}
Here is my Network code :
func loadData() async{
guard let url = Bundle.main.url(forResource: "response", withExtension: "json")
else {
print("Json file not found")
return
}
do {
let (data, _) = try await URLSession.shared.data(from: url)
if let decodedResponse = try? JSONDecoder().decode(StationDataApi.self, from: data) {
results=decodedResponse.results
}
} catch {
print("Invalid data")
}
}
Here is the my View :
struct StationView: View {
@State private var results : [Result] = []
var body: some View {
NavigationView {
List (results, id: \.id){item in
NavigationLink(destination: DetailStationView(stationItem: item)){
VStack(alignment: .leading) {
Text(item.chargingPark.connectors.description)
}
}
}
}
.navigationTitle("Fetch")
.task {
await loadData()
}
}
That is the result that I get. I wanted to display it properly not like a raw json content
CodePudding user response:
connectors
is an array of Connector
, and so you need to decide which
array element you want to display. For example all elements, such as:
VStack(alignment: .leading) {
ForEach(item.chargingPark.connectors, id: \.self) { conector in
Text("connectorType: \(conector.connectorType)")
Text("PowerKw: \(conector.ratedPowerKw)")
Text("voltageV: \(conector.voltageV)")
Text("currentA: \(conector.currentA)")
Text("currentType: \(conector.currentType.rawValue)")
}
}
or the first one as in this example:
VStack(alignment: .leading) {
Text("\(item.chargingPark.connectors.first?.ratedPowerKw ?? 0)")
Text("\(item.chargingPark.connectors.first?.voltageV ?? 0)")
Text("\(item.chargingPark.connectors.first?.currentA ?? 0)")
Text("\(item.chargingPark.connectors.first?.currentType.rawValue ?? "")")
}
Adjust the code and display to your specific needs. Note you may need to use struct Connector: Codable, Hashable {...}
or make Connector
Identifiable.