-2

I'm a newbie Swift programmer and trying to learn about using API calls.

I started making a Weather application with using OpenWeatherMap.

I set everything and able to get the device's location, then get the weather of that location. I can see the location's weather in console logs.

But now I can't find a way to use them as label texts etc. I am able to get only the city name but can't use it outside of the class.

So, my question is, what should I do to use JSON data fetched from API for storyboard labels?

Thanks for any help!

My files :

  • ViewController.swift : Main controller. I get the device's location and use getWeather for get lat and lon so I can send it to WeatherAPI.swift
  • WeatherAPI.swift : Connecting to OpenWeatherMap and fetching datas.
  • Weather.swift : Struct for fetched API data.

ViewController.swift

import CoreLocation


class ViewController: UIViewController, CLLocationManagerDelegate {
    
    var locationManager: CLLocationManager?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        locationManager = CLLocationManager()
        locationManager?.delegate = self
        locationManager?.requestAlwaysAuthorization()
        locationManager?.desiredAccuracy = kCLLocationAccuracyBest
        locationManager?.startUpdatingLocation()
        
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location:CLLocationCoordinate2D = manager.location!.coordinate
        let weather = WeatherAPI()
        
        weather.getWeather(lat: location.latitude, lon: location.longitude)
        
    
        
    }
    
}

WeatherAPI.swift


class WeatherAPI {
    
    private let openWeatherMapAPIKey = "XXX"
    
    func getWeather(lat : Double, lon: Double) {
        var random = "denem"
        let queryItems = [URLQueryItem(name: "lat", value: lat.description), URLQueryItem(name: "lon", value: lon.description), URLQueryItem(name: "APPID", value: openWeatherMapAPIKey)]
        var URLComps = URLComponents(string: "http://api.openweathermap.org/data/2.5/weather")!
        URLComps.queryItems = queryItems
        let url = URLComps.url!
            
        let session = URLSession.shared

        let task = session.dataTask(with: url) { data, response, error in

            if error != nil || data == nil {
                print("Client error!")
                return
            }

            do {
                let weatherItems = try JSONDecoder().decode(CurrentLocalWeather.self, from: data!)
                random = weatherItems.name
                print(random)
            } catch {
                print("JSON error: \(error)")
            }
        }

        task.resume()
    }
}

Weather.swift

struct CurrentLocalWeather: Decodable {
    let base: String
    let clouds: Clouds
    let cod: Int
    let coord: Coord
    let dt: Int
    let id: Int
    let main: Main
    let name: String
    let sys: Sys
    let visibility: Int
    let weather: [Weather]
    let wind: Wind
}
struct Clouds: Decodable {
    let all: Int
}
struct Coord: Decodable {
    let lat: Double
    let lon: Double
}
struct Main: Decodable {
    let humidity: Int
    let pressure: Int
    let temp: Double
    let tempMax: Double
    let tempMin: Double
    private enum CodingKeys: String, CodingKey {
        case humidity, pressure, temp, tempMax = "temp_max", tempMin = "temp_min"
    }
}
struct Sys: Decodable {
    let country: String
    let id: Int
    let message: Double?
    let sunrise: UInt64
    let sunset: UInt64
    let type: Int
}
struct Weather: Decodable {
    let description: String
    let icon: String
    let id: Int
    let main: String
}
struct Wind: Decodable {
    let deg: Int
    let speed: Double
}

oğuz
  • 145
  • 1
  • 13

1 Answers1

-1

Modify the getWeather method parameter to have a completion block at the end like this:

class WeatherAPI {
    //...
    func getWeather(lat : Double, lon: Double, completion: @escaping (CurrentLocalWeather) -> Void) {
        //...
        let task = session.dataTask(with: url) { data, response, error in
            //...
            do {
                let weatherItems = try JSONDecoder().decode(CurrentLocalWeather.self, from: data!)
                completion(weatherItems)
            } catch {
                print("JSON error: \(error)")
            }
        }
        task.resume()
    }
}

And use this method like this:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location:CLLocationCoordinate2D = manager.location!.coordinate
    let weather = WeatherAPI()

    weather.getWeather(lat: location.latitude, lon: location.longitude) { weather in
        print(weather.name)
    }
}
Frankenstein
  • 15,732
  • 4
  • 22
  • 47