简体   繁体   中英

How to extract information from API using Structs and Decodable in Swift 4-5?

I need to extract information from the a json using the openweather website. But I have problems on extracting the information from the "weather" (and any other) part (I need "main" and "description"). I was able to extract (so far) only the coordinates ("coord"). But I'm stuck to get the "weather" section as I mentioned above. I also tried to get the "sys" part to get the "sunrise" and "sunset" variables but I get an error.

I have been capable of getting all of this information using the "guard let" method but now I would like to get it using the "struct decodable" method. Using the "struct decodable" method, I am able to get only the coordinates from the API, but if I try to add any other element in the struct, it says that "Type 'Elements' does not conform to protocol 'Decodable'". It is here were I get stuck. If I remove the // in the struct Elements:Decodable I get the error mentioned above.

This is my current code so far:

import UIKit
import CoreLocation

//MARK: - Structures to parse the JSON in the Openweather API.
struct Elements:Decodable {

    let coord:[String:Double]
//  let weather:[String:Any]
//      let sys:[String:Any]    
}

//MARK: Class ViewController
class ViewController: UIViewController {

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

        let jsonURL = "some URL that I can't provide you guys since it has a private key that I can't share, sorry :C "
        guard let url = URL(string: jsonURL) else{return}

        URLSession.shared.dataTask(with: url) { (data, response, err) in

            guard let data = data else{return}

            do{

                let weather = try JSONDecoder().decode(Elements.self, from: data)
                print("Coordinates: ", weather.coord)
                print("Longitude: ", weather.coord["lon"]!)
                print("Latitude: ", weather.coord["lat"]!)
                print("Weather: ", weather.weather)

            }catch let jsonErr{

                print("Error serializing Json: ", jsonErr)

            }

        }.resume()

    }

}

This is the JSON:

{
"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
  }

I try to print the results but I get "Type 'Elements' does not conform to protocol 'Decodable'".

Your struct structure should be in the form the api returns it so when decoding it understand.

 Struct Element: Decodable{ Var coord: coordinate Var weather: weatherValue } Struct coordinate: Decodable { Var Lon : String Var lat : String } Struct weatherValue : Decodable { Var id : Int Var main : String Var description: String Var icon : String Var base : String }

NB : Decodable only conforms to String, int ,double ,array float....The variable you declare in element struct should be the same as in the api except you want to change the name using codingKeys

These are the structs for the weather API of openweathermap

struct WeatherData : Decodable {
    let coord : Coordinate
    let cod, visibility, id : Int
    let name : String
    let base : String
    let weather : [Weather]
    let sys : Sys
    let main : Main
    let wind : Wind
    let dt : Date
}

struct Coordinate : Decodable {
    let lat, lon : Double
}

struct Weather : Decodable {
    let id : Int
    let icon : String
    let main : MainEnum
    let description: String
}

struct Sys : Decodable {
    let type, id : Int
    let sunrise, sunset : Date
    let message : Double
    let country : String
}

struct Main : Decodable {
    let temp, tempMin, tempMax : Double
    let pressure, humidity : Int
}

struct Wind : Decodable {
    let speed : Double
    let deg : Double?
    let gust : Double?
}

enum MainEnum: String, Decodable {
    case clear = "Clear"
    case clouds = "Clouds"
    case rain = "Rain"
} 

You have to add a date and key decoding strategy to be able to decode the date integers as Date and to handle the snake_cased keys

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    decoder.dateDecodingStrategy = .secondsSince1970
    let weatherData = try decoder.decode(WeatherData.self, from: data)
    print("Coordinates: ", weatherData.coord)
    print("Longitude: ", weatherData.coord.lon)
    print("Latitude: ", weatherData.coord.lat)
    print("Weather: ", weatherData.weather)

} catch {
    print("Error serializing Json: ", error)
}

Here I share 3 possible options (using "if let", using "guard let" and using "Codable").

If let method:

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
    if let urlJSONOpenWeather = URL(string: "http://api.openweathermap.org/data/2.5/weather?lat=51.9946&lon=4.378799&appid=get_api_id_for_openweather"){

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

            if error == nil{

                if let urlContent = data{

                    do {

                        let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
                        print("This is jsonResult: ", jsonResult)
                        print("---------------------")

                        if let coordinates = (jsonResult["coord"] as? NSDictionary), let longitude = coordinates["lon"] as? NSNumber, let latitude = coordinates["lat"] as? NSNumber{

                            print("Longitude: \(longitude)º")
                            print("Latitude: \(latitude)º")
                            print("---------------------")

                        }

                        if let weatherData = (jsonResult["weather"] as? Array<[String:Any]>){

                            print("Weather data array: \(weatherData)")

                            print("Weather id: ", weatherData[0]["id"]!)
                            print("Weather main: ", weatherData[0]["main"]!)
                            print("Weather description: ", weatherData[0]["description"]!)
                            print("Weather icon: ", weatherData[0]["icon"]!)
                            print("---------------------")

                        }

                        if let mainValues = (jsonResult["main"] as? NSDictionary), let temperatureK = mainValues["temp"] as? NSNumber, let pressure = mainValues["pressure"] as? NSNumber, let humidity = mainValues["humidity"] as? NSNumber{

                            print("Temperature in Kelvin: \(temperatureK) K")

                            let tempKString = (temperatureK as AnyObject).description
                            var tempCelsius = (tempKString! as NSString).floatValue
                            tempCelsius = tempCelsius - 273.15
                            print("Temperature in Celsius: \(String(format:"%.2f", tempCelsius))ºC")

                            print("Pressure: \(pressure) hPa")
                            print("Humidity: \(humidity)%")
                            print("---------------------")

                        }

                        if let wind = (jsonResult["wind"] as? NSDictionary)? ["speed"]{

                            print("Wind speed: \(wind) m/s")
                            print("---------------------")

                        }

                        if let sysData = (jsonResult["sys"] as? NSDictionary), let country = sysData["country"] as? NSString, let sunriseValue = sysData["sunrise"] as? NSNumber, let sunsetValue = sysData["sunset"] as? NSNumber{

                            print("Country code: \(country)")

                            //Give a format to the time
                            let formatter = DateFormatter()
                            formatter.dateStyle = .none
                            formatter.timeStyle = .medium
                            formatter.dateFormat = "HH:mm:ss"

                            //First we get the sunrise time.
                            let sunriseDate = Date(timeIntervalSince1970: sunriseValue.doubleValue)
                            print("Sunrise date: \(sunriseDate)")

                            let sunrise = formatter.string(from: sunriseDate)
                            print("Sunrise: \(sunrise)")

                            //First we get the sunrset time.
                            let sunsetDate = Date(timeIntervalSince1970: sunsetValue.doubleValue)
                            print("Sunrise date: \(sunsetDate)")

                            let sunset = formatter.string(from: sunsetDate)
                            print("Sunset: \(sunset)")
                            print("---------------------")

                        }

                    }catch{

                        print("JSON Processing failed.")

                    }

                }

            } else {

                print("Error during JSON parsing: ", error!)

            }

        }

        OpenWeatherTask.resume()

    }

    if 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"){

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

            if error == nil{

                if let urlContent = data {

                    do{

                        let jsonResult = try JSONSerialization.jsonObject(with: urlContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]

                        if let features = (jsonResult["features"] as? Array<[String:Any]>){

                            print("Features: ", features)
                            print("---------------------")

                            if let singleFeature = features.first {

                                print("Single feature: ", singleFeature)
                                print("---------------------")

                                if let geometry = singleFeature["geometry"] as? [String:Any]{

                                    let coordinates = geometry["coordinates"] as? Array<Double>
                                    print("Coordinates: ", coordinates!)

                                    let nasaLon = coordinates?[0]
                                    let nasaLat = coordinates?[1]
                                    print("NASA Latitude: \(String(describing: nasaLat!))º | NASA Longitude: \(String(describing: nasaLon!))º")
                                    print("---------------------")

                                }

                                if let properties = singleFeature["properties"] as? [String:Any], let parameter = properties["parameter"] as? [String:Any]{

                                    print("Properties: ", properties)
                                    print("Parameter: ", parameter)

                                    let ghi_raw = parameter["ALLSKY_SFC_SW_DWN"] as? [String:Double]
                                    print("GHI raw: ", ghi_raw!)
                                    let dhi_raw = parameter["DIFF"] as? [String:Double]
                                    print("DHI raw: ", dhi_raw!)
                                    let dni_raw = parameter["DNR"] as? [String:Double]
                                    print("DNI raw: ", dni_raw!)
                                    print("---------------------")

                                    // 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("DNI ordered: ", self.DNI)
                                    print("DHI ordered: ", self.DHI)
                                    print("GHI ordered: ", self.GHI)
                                    print("---------------------")

                                }

                            }

                        }

                        if let parameterInformation = jsonResult["parameterInformation"] as? [String:Any]{

                            if let ghiDwn = parameterInformation["ALLSKY_SFC_SW_DWN"] as? [String:Any]{

                                print("GHI Dwn: ", ghiDwn)
                                print(ghiDwn["units"]!)
                                print(ghiDwn["longname"]!)

                            }

                            if let diffDwn = parameterInformation["DIFF"] as? [String:Any]{

                                print("DHI Dwn: ", diffDwn)
                                print(diffDwn["units"]!)
                                print(diffDwn["longname"]!)

                            }

                            if let dniDwn = parameterInformation["DNR"] as? [String:Any]{

                                print("DNI Dwn: ", dniDwn)
                                print(dniDwn["units"]!)
                                print(dniDwn["longname"]!)

                            }

                        }

                        print("--------------------------")

                    }catch{

                        print("Error retrieving NASA's JSON: ", error)

                    }

                }

            } else{

                print("Error by retrieving the NASA's JSON: ", error!)

            }

        }

        NASATask.resume()

    }

}

}

Guard let method:

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_for_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 urlOpenWeatherContent = data else{ return }
            print("urlOpenWeatherContent: \(urlOpenWeatherContent)")

            do {

                let openWeatherJSONResult = try JSONSerialization.jsonObject(with: urlOpenWeatherContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
                print("This is the openWeatherJSONResult:\n \(openWeatherJSONResult)")
                print("-----------------")

                // MARK: - Extract the coordinates (latitude and longitude) from the "coord" dictionary
                guard let coordinates = openWeatherJSONResult["coord"] as? [String:Any] else{

                    print("There was an error in 'coordinates'.")
                    return

                }

                print("These are the coordinates: ", coordinates)
                print("Latitude: \(coordinates["lat"]!)º")
                print("Longitude: \(coordinates["lon"]!)º")
                print("-----------------")

                // MARK: - Extract the weather from the an array of dictionaries
                guard let weatherArray = openWeatherJSONResult["weather"] as? Array<[String:Any]> else {

                    print("There was an error in 'weather'.")
                    return

                }

                print("This is the 'weather' array: ", weatherArray)
                print("-----------------")

                guard let weather = weatherArray.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: - Extract the atmospheric characteristics from the "main" dictionary
                guard let main = openWeatherJSONResult["main"] as? [String:Double] else {

                    print("There was an error in 'main'.")
                    return

                }

                print("Temperature in Kelvin: \(String(main["temp"]!)) K")

                let tempInCelsius = main["temp"]! - 273.15
                print("Temperature in Celsius: \(String(format:"%.2f", tempInCelsius))ºC")
                print("Pressure in hPa: \(String(main["pressure"]!))")
                print("Humidity: \(String(main["humidity"]!)) %")
                print("-----------------")

                // MARK: - Extract the wind speed
                guard let wind = openWeatherJSONResult["wind"] as? [String:Double] else {

                    print("There was an error in 'wind'.")
                    return

                }

                print("Wind speed: \(String(wind["speed"]!)) m/s")
                print("-----------------")

                // MARK: - Extract country, sunrise and sunset
                guard let sys = openWeatherJSONResult["sys"] as? [String:Any] else {

                    print("There was an error in 'sys' to extract country, sunrise and sunset.")
                    return

                }

                print("Country: \(sys["country"]!)")

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

                // Second, determine sunrise date and get sunrise time
                let sunriseValue = sys["sunrise"]
                print("Type of sunrise value: \(type(of: sunriseValue))")
                let sunriseDate = Date(timeIntervalSince1970: sunriseValue as! TimeInterval)
                print("Sunrise date: \(sunriseDate)")

                let sunrise = formatter.string(from: sunriseDate)
                print("Sunrise: \(sunrise)")

                // Finally, determine sunset date and sunset time
                let sunsetValue = sys["sunset"]
                let sunsetDate = Date(timeIntervalSince1970: sunsetValue as! TimeInterval)

                let sunset = formatter.string(from: sunsetDate)
                print("Sunset: \(sunset)")
                print("-----------------")

            } catch {

                print("Open Weather JSON Processing failed.")

            }

        } else {

            print("There was an error inside openWeatherTask: ", error!)

        }

    }

    openWeatherTask.resume()

    // MARK: - NASA LARC 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

    }

    print("NASA URL API: \(urlJSONNASA)")

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

        if error == nil {

            guard let urlNASAContent = data else{ return }

            do{

                let nasaJSONResult = try JSONSerialization.jsonObject(with: urlNASAContent, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String:Any]
                print("-----------------")

                guard let features = nasaJSONResult["features"] as? Array<[String:Any]> else {

                    print("Error retrieving 'features'.")
                    return

                }

                print("This is the 'features' array:", features)
                print("-----------------")

                guard let singleFeature = features.first else{

                    print("Error retrieving 'singleFeature'.")
                    return

                }

                guard let geometry = singleFeature["geometry"] as? [String:Any] else {

                    print("Error retrieving 'geometry'.")
                    return

                }

                print("Geometry: ", geometry)
                let coordinates = geometry["coordinates"] as? Array<Double>

                print("Coordinates: ", coordinates!)
                let nasaLat = coordinates?[1]
                let nasaLon = coordinates?[0]
                print("NASA Latitude: \(String(describing: nasaLat!))º | NASA Longitude: \(String(describing: nasaLon!))º")
                print("---------------------")

                guard let properties = singleFeature["properties"] as? [String:Any] else{

                    print("Error retrieving 'properties'.")
                    return

                }

                let parameter = properties["parameter"] as? [String:Any]
                print("Parameters: ", parameter!)

                let ghi_raw = parameter!["ALLSKY_SFC_SW_DWN"] as? [String:Double]
                print("GHI raw: ", ghi_raw!)

                let dhi_raw = parameter!["DIFF"] as? [String:Double]
                print("DHI raw: ", dhi_raw!)

                let dni_raw = parameter!["DNR"] as? [String:Double]
                print("DNI raw: ", dni_raw!)
                print("---------------------")

                // 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("DNI ordered: ", self.DNI)
                print("DHI ordered: ", self.DHI)
                print("GHI ordered: ", self.GHI)
                print("---------------------")

                guard let parameterInformation = nasaJSONResult["parameterInformation"] as? [String:Any] else {

                    print("Error retrieving 'parameterInformation'.")
                    return

                }

                print("ParameterInformation: ", parameterInformation)
                print("---------------------")

                guard let ghi_paramInfo = parameterInformation["ALLSKY_SFC_SW_DWN"] as? [String:Any] else {

                    print("Error retriving the GHI inside the parameter information.")
                    return

                }

                print("GHI in parameter information: ", ghi_paramInfo)
                print("Long name of GHI in parameter information: ", ghi_paramInfo["longname"]!)
                print("Units of GHI in parameter information: ", ghi_paramInfo["units"]!)
                print("---------------------")

                guard let dhi_paramInfo = parameterInformation["DIFF"] as? [String:Any] else {

                    print("Error retrieving the DHI inside the parameter information.")
                    return

                }

                print("DHI in parameter information: ", dhi_paramInfo)
                print("Long name of GHI in parameter information: ", dhi_paramInfo["longname"]!)
                print("Units of GHI in parameter information: ", dhi_paramInfo["units"]!)
                print("---------------------")

                guard let dni_paramInfo = parameterInformation["DNR"] as? [String:Any] else{

                    print("Error retrieving the DHI inside the parameter information.")
                    return

                }

                print("DNI in parameter information: ", dni_paramInfo)
                print("Long name of DNI in parameter information: ", dni_paramInfo["longname"]!)
                print("Units of DNI in parameter information: ", dni_paramInfo["units"]!)
                print("---------------------")

            } catch {

                print("NASA JSON processing failed.")

            }

        } else {

            print("There was an error inside the nasaTask: ", error!)

        }

    }

    nasaTask.resume()

}

}

Codable method:

//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()

}

}

I hope this may be helpful for someone in the future. Greets.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM