-1
votes

Comment extraire des informations d'API à l'aide des structures et décodable à Swift 4-5?

J'ai besoin d'extraire des informations de la JSON A à l'aide du site Web OpenWeather. Mais j'ai des problèmes pour extraire les informations de la partie "météo" (et toute autre partie) (j'ai besoin de "principale" et "description"). J'ai pu extraire (jusqu'à présent) uniquement les coordonnées ("coordonnées"). Mais je suis coincé pour obtenir la section "météo" comme je l'ai mentionné ci-dessus. J'ai également essayé d'obtenir la partie "SYS" pour obtenir les variables "Sunrise" et "Sunset", mais je reçois une erreur.

J'ai été capable d'obtenir toutes ces informations à l'aide de la méthode "Guard Let", mais maintenant je Voudrais l'obtenir en utilisant la méthode "Struct décodable". Utilisation de la méthode "Struct décodable", je suis capable d'obtenir uniquement les coordonnées de l'API, mais si j'essaie d'ajouter un autre élément de la structure, il est indiqué que "les éléments" de type "ne sont pas conformes au protocole" décodable "" . C'est ici que je suis coincé. Si je supprimais le // dans les éléments de structure: décodable, je reçois l'erreur mentionnée ci-dessus. P>

Ceci est mon code actuel jusqu'à présent: p>

{
"coord":
    {"lon":-3.74,"lat":40.39},
"weather":
    [
      {
       "id":800,
       "main":"Clear",
       "description":"clear sky",
       "icon":"01d"
      }
     ],
"base":"stations",
"main":    
  {
    "temp":291.47,
    "pressure":1027,
    "humidity":42,
    "temp_min":290.37,
    "temp_max":293.15
  },
"visibility":10000,
"wind":
  {
    "speed":1.5
  },
"clouds":
  {
    "all":0
  },
 "dt":1556368766,
"sys": 
  {
    "type":1,
    "id":6443,
    "message":0.0065,
    "country":"ES",
    "sunrise":1556342391,
    "sunset":1556391910},
    "id":6355233,
    "name":"Provincia de Madrid",
    "cod":200
  }


3 commentaires

Veuillez poster le vrai Json (avec toutes les ponctuations nécessaires).


Vous ne pouvez pas utiliser aucun dans décodable . Créez la propriété des structures imbriquées à la place. Il y a d'innombrables exemples. Même beaucoup en utilisant l'API Open Weather, cela semble provenir de.


merci pour votre réponse rmaddy. Comme je l'ai dit auparavant, j'ai suivi certains tutoriels qui fonctionnent avec l'exmaple montré dans la vidéo, mais lorsque j'essaie de l'appliquer sur mon projet, cela ne fonctionne pas. C'est pourquoi j'ai demandé ici. J'ai déjà mis à jour la question en ajoutant le JSON avec sa ponctuation. Merci encore.


3 Réponses :


0
votes

Votre structure de structure doit être sous la forme de l'API le renvoie afin de le décoder.

xxx

N.B: Decodable ne se conforme qu'à la chaîne, int, double, flotteur de matrice .... La variable que vous déclarez dans l'élément STRL doit être la même que dans l'API, sauf que vous souhaitez modifier le nom à l'aide de CODINGKEYS


0 commentaires

0
votes

Ce sont les structures de la météo API de OpenWeatherMap xxx

Vous devez ajouter une date et décodage de clé stratégie pour pouvoir décoder les entiers de la date d'entiers tels que date et pour gérer les touches snake_cased xxx


3 commentaires

Merci Vadian. Je vais essayer.


Bonjour Vadian. Je vérifiais le code et j'ai découvert que je ne peux pas obtenir les informations individuelles de la partie "météo", j'ai imprimé weatherdata.weather et moi avons eu ceci: conditions météorologiques: [Structapi.weather (id: 800, icon: " 01n ", Main: Structapi.Mainenum.clear, Description:" Clear Sky ")]. Mais je ne peux pas extraire les informations individuelles de cette structure (ID, icône et description). J'ai essayé d'imprimer des weatherdata.weather.weather mais évidemment ça ne marche pas. J'apprécie le temps que vous avez mis pour m'aider. Merci d'avance.


S'il vous plaît (apprendre à) lire le JSON. Météo est une matrice (notez le [] ). Vous devez utiliser une boucle ou obtenir le premier élément avec weatherdata.weather.first!



0
votes

Ici, je partage 3 options possibles (en utilisant "si laisse", en utilisant "Guard let" et en utilisant "codable").

Si la méthode de la lettre suivante: p> xxx pré>

Méthode de protection: p> xxx pré>

méthode codable: p>

//MARK: - Structs to get the information from the openWeather API
struct OWElements:Codable {
var coord:CoordinatesDetails
var weather:[WeatherDetails]
var main:MainDetails
var wind:WindDetails
var sys:SysDetails
var name:String
}

struct CoordinatesDetails:Codable {
var lon:Float
var lat:Float
}

struct WeatherDetails:Codable {
var id:Int
var main:String
var description:String
var icon:String
}

struct MainDetails:Codable {
var temp:Float
var pressure:Float
var humidity:Float
var temp_min:Float
var temp_max:Float
}

struct WindDetails:Codable {
var speed:Float
var deg:Int
}

struct SysDetails:Codable {
var type:Int
var id:Int
var message:Float
var country:String
var sunrise:Int
var sunset:Int
}

//MARK: - Structs to get the information from the NASA API
struct NASAElements:Codable {
var features:[FeaturesDetails]
var parameterInformation:ParameterInformationDetails
}

struct FeaturesDetails:Codable {
var geometry:GeometryDetails
var properties:PropertiesDetails
}

struct GeometryDetails:Codable {
var coordinates:[Double]
}

struct PropertiesDetails:Codable {
var parameter:ParameterDetails
}

struct ParameterDetails:Codable {
var ALLSKY_SFC_SW_DWN:[String:Double]
var DIFF:[String:Double]
var DNR:[String:Double]
}

struct ParameterInformationDetails:Codable {
var ALLSKY_SFC_SW_DWN:ALLSKY_SFC_SW_DWNDetails
var DIFF:DIFFDetails
var DNR:DNRDetails
}

struct ALLSKY_SFC_SW_DWNDetails:Codable {
var longname:String
var units:String
}

struct DIFFDetails:Codable {
var longname:String
var units:String
}

struct DNRDetails:Codable {
var longname:String
var units:String
}

// MARK: - Class ViewController
class ViewController: UIViewController {

// MARK: - Variables and constants
var DNI = [Double](repeating: 0.0, count: 12)
var DHI = [Double](repeating: 0.0, count: 12)
var GHI = [Double](repeating: 0.0, count: 12)

// MARK: - Method viewDidLoad()
override func viewDidLoad() {
    super.viewDidLoad()

    // MARK: Open Weather API
    guard let urlJSONOpenWeather = URL(string: "http://api.openweathermap.org/data/2.5/weather?lat=51.9946&lon=4.378799&appid=get_api_id_openweather") else {

            print("There was an error on retrieving the Open Weather JSON url.")
            return

    }

    let openWeatherTask = URLSession.shared.dataTask(with: urlJSONOpenWeather) { (data, response, error) in

        if error == nil{

            guard let urlOpenWeatherData = data else{

                print("Error in the guard let urlOpenWeatherData")
                return

            }

            do {

                let openWeatherElements = try JSONDecoder().decode(OWElements.self, from: urlOpenWeatherData)
                print("This is the openWeather Elements:\n \(openWeatherElements)")

                // MARK: - Getting the coordinates (latitude and longitude)
                let openWeatherLatitude = openWeatherElements.coord.lat
                let openWeatherLongitude = openWeatherElements.coord.lon
                print("OpenWeather Latitude:\n \(openWeatherLatitude)º")
                print("OpenWeather Longitude:\n \(openWeatherLongitude)º")
                print("-----------------")

                // MARK: - Getting the weather description from an array of dictionary.
                let openWeatherWeatherArray = openWeatherElements.weather
                print("OpenWeather Weather Array:\n \(openWeatherWeatherArray)")

                guard let weather = openWeatherWeatherArray.first else {

                    print("There was an error on retrieving the elements of the 'weather' array.)")
                    return

                }

                print("These are the weatherArray elements: ", weather)
                print("ID: \(weather.id)")
                print("Main: \(weather.main)")
                print("Description: \(weather.description)")
                print("Icon: \(weather.icon)")
                print("-----------------")

                // MARK: - Getting the "main" elements
                let main = openWeatherElements.main
                print("This is main:\n \(main)")
                print("Temperature in Kelvin: \(main.temp)K")
                print("Pressure: \(main.pressure) hPa")
                print("Humidity: \(main.humidity)")

                let tempInCelsius = main.temp - 273.15
                print("Temperature in Celsius: \(String(format:"%.2f", tempInCelsius))ºC")

                let maxTempCelsius = main.temp_max - 273.15
                print("Max temperature in Kelvin: \(main.temp_max)K")
                print("Max temperature in Celsius: \(String(format:"%.2f", maxTempCelsius))ºC")

                let minTempCelsius = main.temp_min - 273.15
                print("Min temperature in Kelvin: \(main.temp_min)K")
                print("Min temperature in Celsius: \(String(format:"%.2f", minTempCelsius))ºC")
                print("-----------------")

                let windDetails = openWeatherElements.wind
                print("Wind speed: \(windDetails.speed)m/s")
                print("Wind direction: \(windDetails.deg)º")
                print("-----------------")

                let sysDetails = openWeatherElements.sys
                print("Type: \(sysDetails.type)")
                print("ID: \(sysDetails.id)")
                print("Message: \(sysDetails.message)")
                print("Country: \(sysDetails.country)")
                print("Sunrise: \(sysDetails.sunrise)")
                print("Sunset: \(sysDetails.sunset)")

                // First, we create a format of time for the sunrise and sunset
                let formatter = DateFormatter()
                formatter.dateStyle = .none
                formatter.dateStyle = .medium
                formatter.dateFormat = "HH:mm:ss"

                // Second, determine sunrise date and get sunrise time
                let sunriseValue = sysDetails.sunrise
                print("Sunrise Value: \(sunriseValue)")

                let sunriseDate = Date(timeIntervalSince1970: Double(sunriseValue))
                print("Sunrise date: \(sunriseDate)")

                let sunsetValue = sysDetails.sunset
                let sunsetDate = Date(timeIntervalSince1970: Double(sunsetValue))
                print("Sunset date: \(sunsetDate)")

                // Finally, determine sunset date and sunset time
                let sunrise = formatter.string(from: sunriseDate)
                let sunset = formatter.string(from: sunsetDate)
                print("Sunrise: \(sunrise)")
                print("Sunset: \(sunset)")
                print("-----------------")

                print("Region: \(openWeatherElements.name)")
                print("-----------------")
            }catch{

                print("Open Weather JSON Processing failed: \(error.localizedDescription)")

            }

        }

    }

    openWeatherTask.resume()

    //MARK: - NASA API
    guard let urlJSONNASA = URL(string: "https://power.larc.nasa.gov/cgi-bin/v1/DataAccess.py?request=execute&identifier=SinglePoint&parameters=DNR,DIFF,ALLSKY_SFC_SW_DWN&userCommunity=SSE&tempAverage=CLIMATOLOGY&outputList=JSON&lat=51.994693&lon=4.378553&user=anonymous") else{

        print("Could not retrieve the URL of NASA")
        return

    }

    let nasaTask = URLSession.shared.dataTask(with: urlJSONNASA) { (data, response, error) in

        if error == nil {

            guard let nasaData = data else{

                print("Error in the guard let nasaData")
                return

            }

            do{

                let nasaElements = try JSONDecoder().decode(NASAElements.self, from: nasaData)
                print("These are the NASA elements:\n \(nasaElements)")
                print("-----------------")

                let featuresArray = nasaElements.features
                print("Features as Array:\n \(featuresArray)")

                guard let features = featuresArray.first else{
                    print("There was an error on retrieving the elements of the 'features' array in the NASA API.)")
                    return
                }

                print("Features: \(features)")

                let geometry = features.geometry
                print("Geometry: \(geometry)")

                let NASALatitude = geometry.coordinates[1]
                let NASALongitude = geometry.coordinates[0]
                print("NASA Latitude: \(NASALatitude)º")
                print("NASA Longitude: \(NASALongitude)º")
                print("-----------------")

                let properties = features.properties
                print("Properties:\n \(properties)")
                print("-----------------")

                let parameter = properties.parameter
                print("Parameters:\n \(parameter)")
                print("-----------------")

                let ghi_raw = parameter.ALLSKY_SFC_SW_DWN
                let dni_raw = parameter.DNR
                let dhi_raw = parameter.DIFF

                print("GHI raw: \(dni_raw)")
                print("DNI raw: \(dni_raw)")
                print("DHI raw: \(dhi_raw)")

                // Put an order on each irradiance
                for index in 1...12{

                    self.DNI[index - 1] = (dni_raw[String(index)])!
                    self.DHI[index - 1] = (dhi_raw[String(index)])!
                    self.GHI[index - 1] = (ghi_raw[String(index)])!

                }

                print("GHI ordered: ", self.GHI)
                print("DNI ordered: ", self.DNI)
                print("DHI ordered: ", self.DHI)
                print("---------------------")

                let parameterInformation = nasaElements.parameterInformation
                print("Parameter Information:\n \(parameterInformation)")

                let ghiInfo = parameterInformation.ALLSKY_SFC_SW_DWN
                let dniInfo = parameterInformation.DNR
                let dhiInfo = parameterInformation.DIFF

                print("GHI Info: \(ghiInfo)")
                print("DNI Info: \(dniInfo)")
                print("DHI Info: \(dhiInfo)\n")

                print("GHI name: \(ghiInfo.longname)")
                print("GHI units: \(ghiInfo.units)\n")
                print("DNI name: \(dniInfo.longname)")
                print("DNI units: \(dniInfo.units)\n")
                print("DHI name: \(dhiInfo.longname)")
                print("DHI units: \(dhiInfo.units)\n")
                print("---------------------")

            } catch {

                print("NASA JSON Processing failed: \(error.localizedDescription)")

            }

        }

    }

    nasaTask.resume()

}

}


0 commentaires