j’ai besoin de votre aide je n’arrive pas à décoder un json avec Xcode Swift UI
je suis très nul dans cet exercice
import Foundation
struct musee:Decodable {
var region_administrative:String
var departement:String
var identifiant_museofile:String
var commune:String
var nom_officiel_du_musee:String
var adresse:String
var code_postal:String
var telephone:String
var url:String
var latitude:Double
var longitude:Double
var geolocalisation:geolocalisation
}
struct geolocalisation:Decodable {
var lon:Double
var lat:Double
}
import Foundation
import SwiftUI
@Observable
class AccesDonnees {
var listeMusee:[musee] = []
var chargementDonnees:Bool = false
var ChargementExplication = "Chargement en cours"
func connexionJson() async {
let statusTache = Task {() in
// verification chaine de type url
guard let urlString = URL(string: "https://data.culture.gouv.fr/api/explore/v2.1/catalog/datasets/liste-et-localisation-des-musees-de-france/records?limit=20") else {return}
do {
// connexion url session
let (mesDonnees, _) = try await URLSession.shared.data(from: urlString)
let musees = try JSONDecoder().decode(musee.self, from: mesDonnees)
print("contenu des donnees :\(musees)")
} catch {
print(error)
print(error.localizedDescription)
}
}
let resultatTache = await statusTache.result
switch resultatTache {
case .success( _):
await MainActor.run {
// self.ChargementExplication = "Chargement terminé"
// DispatchQueue.main.asyncAfter(deadline: .now() + 1.7) {
// self.chargementDonnees = true
// }
}
//} // fin de la tâche
l'erreur que me retourne la console :
keyNotFound(CodingKeys(stringValue: "region_administrative", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"region_administrative\", intValue: nil) (\"region_administrative\").", underlyingError: nil))
The data couldn’t be read because it is missing.
un navigateur me retourne bien les données avec l'url https://data.culture.gouv.fr/api/explore/v2.1/catalog/datasets/liste-et-localisation-des-musees-de-france/records?limit=20
donc je me dit que l'erreur vient de mon fichier struct ou de ma ligne pour décodé
let musees = try JSONDecoder().decode(musee.self, from: mesDonnees)
Merci de votre aide
Il te retourne un tableau « Results » avec les éléments que tu traites dedans.
Il faut que tu le traites en conséquence, en créant un tableau « Results » qui contiendra tes données.
Tu as un exemple ici :
Ce qui donnerait une struct en plus genre :
Struct Results: Codable {
var ListeMusee: [musee]
}
A ce moment la, il devrait pouvoir lire le contenu du JSON en traitant la struct Results. dans le ‹ JSONDecoder() ›
Petites remarques : attention au nommage de tes class/struct → avec un Majuscule au début.
Ton JSON est rempli, mais si un des éléments ne contient rien? il faudrait mieux passer par du conditionnel avec un retour erreur si jamais l’un des éléments est ‹ nil ›.
@Mrt1 a déjà trouvé d’où venait le problème mais, comme moi, tu es « nul » dans cet exercice de coder/decoder un json, je te conseille ce site internet qui fait (presque) tout pour toi !
Tu copies le json dans la fenêtre de gauche et paramètre quelques options dans le volet de droite pour obtenir le/les classes/structs a créer.
Par example, les fichiers proposés pour ton API sont :
import Foundation
enum RegionAdministrative: String, Codable, Hashable {
case auvergneRhôneAlpes = "Auvergne-Rhône-Alpes"
case bourgogneFrancheComté = "Bourgogne-Franche-Comté"
case bretagne = "Bretagne"
case centreValDeLoire = "Centre-Val de Loire"
case corse = "Corse"
case grandEst = "Grand Est"
case hautsDeFrance = "Hauts-de-France"
}
JSONSchemaSupport.swift
import Foundation
// MARK: - Helper functions for creating encoders and decoders
func newJSONDecoder() -> JSONDecoder {
let decoder = JSONDecoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
decoder.dateDecodingStrategy = .iso8601
}
return decoder
}
func newJSONEncoder() -> JSONEncoder {
let encoder = JSONEncoder()
if #available(iOS 10.0, OSX 10.12, tvOS 10.0, watchOS 3.0, *) {
encoder.dateEncodingStrategy = .iso8601
}
return encoder
}
Quand je dis qu’il y a quand même un peu de travail manuel à faire, je fais référence par example au fichier RegionAdministrative.swift qui n’est pas exhaustif (requête sur API est limitée a 100 enregistrements) ou encore aux caractères spéciaux des variables auvergneRhôneAlpes ou bourgogneFrancheComté que je supprimerais…