Agenda
struct WeatherService { // 3 functions here }
struct WeatherService { public func fetchCurrentWeather( completion: ((Weather) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(Weather.self, from: data) completion?(json) } catch let error{ print("Fetch error.") print(error) } }.resume() } // 2 more functions here }
struct WeatherService { public func fetchCurrentWeather( completion: ((Weather) -> Void)? = nil) { //... completion?(json) //... } // 2 more functions here }
public func hello( completion: ((String)->Void)?=nil) { completion?("Result Here") }
struct WeatherService { public func fetchCurrentWeather( completion: ((Weather) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(Weather.self, from: data) completion?(json) } catch let error{ print("Fetch error.") print(error) } }.resume() } public func fetchForecastWeather( completion: (([ForecastDay]) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(Forecast.self, from: data) completion?(json.forecasts) } catch let error{ print("Fetch error.") print(error) } }.resume() } // 1 more function here }
struct WeatherService { public func fetchCurrentWeather( completion: ((Weather) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(Weather.self, from: data) completion?(json) } catch let error{ print("Fetch error.") print(error) } }.resume() } public func fetchForecastWeather( completion: (([ForecastDay]) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(Forecast.self, from: data) completion?(json.forecasts) } catch let error{ print("Fetch error.") print(error) } }.resume() } public func fetchCitiesWeather( completion: (([CityWeather]) -> Void)? = nil) { guard let url = URL(string: "https://dev.makzan.net/cities_weather.json") else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in guard let data = data else { return } if error != nil { print(error!) return } do { let json = try JSONDecoder().decode(CitiesWeather.self, from: data) completion?(json.cities) } catch let error{ print("Fetch error.") print(error) } }.resume() } // 1 more function here }
struct Weather:Decodable { var date: String = "" var temperature: String = "" var humidity: String = "" var windSpeed: String = "" var windDescription: String = "" var today:String = "" var statusCode:String = "" var todayDescription = "" var tomorrowDescription = "" }
struct Forecast:Decodable { var forecasts: [ForecastDay] = [] } struct ForecastDay:Decodable { var date:String = "" var statusCode:String = "" var temperatureLow:String = "" var temperatureHigh:String = "" var description:String = "" }
struct CitiesWeather:Decodable { var cities: [CityWeather] = [] } struct Coordinate:Decodable { var latitude: Double var longitude: Double } struct CityWeather:Decodable { var cityName:String = "" var date:String = "" var temperatureLow:String = "" var temperatureHigh:String = "" var description:String = "" var coordinate:Coordinate }
struct StatusCode { // https://xml.smg.gov.mo/#Status static let statusCodes = [ "01": "sun.max.fill", "a1": "moon.fill", "02": "cloud.sun.fill", "a2": "cloud.moon.fill", "03": "cloud.fill", "04": "cloud.fill", "12": "cloud.rain.fill", "13": "cloud.rain.fill", "16": "cloud.heavyrain.fill", "17": "cloud.heavyrain.fill", "18": "cloud.bolt.rain.fill", "25": "cloud.bolt.fill", "27": "cloud.rain.fill", "28": "cloud.rain.fill", "c8": "cloud.moon.rain.fill", "29": "cloud.rain.fill", "c9": "cloud.moon.rain.fill", ] static func symbolFor(statusCode:String) -> String { return statusCodes[statusCode] ?? "sun.fill" } }
import MapKit
import UIKit import MapKit class CitiesMapViewController: UIViewController { @IBOutlet weak var mapView: MKMapView! var cities: [CityWeather] = [] override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let coordinate = CLLocationCoordinate2D(latitude: 32.59037534587093, longitude: 114.95212987586083) // 5,000KM x 3,000KM let region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 5000*1000, longitudinalMeters: 3000*1000) mapView.setRegion(region, animated: false) // fetch cities weather WeatherService().fetchCitiesWeather { (cities) in self.cities = cities DispatchQueue.main.async { self.renderCities() } } } func renderCities() { var annotations: [MKAnnotation] = [] for city in cities { let annotation = MKPointAnnotation() annotation.coordinate = CLLocationCoordinate2D(latitude: city.coordinate.latitude, longitude: city.coordinate.longitude) annotation.title = city.cityName annotation.subtitle = "\(city.temperatureLow)—\(city.temperatureHigh) \(city.description)" annotations.append(annotation) } mapView.addAnnotations(annotations) } }
import SafariServices
@IBAction func tapDetails(_ sender: Any) { guard let url = URL(string: "https://www.smg.gov.mo/") else { return } let vc = SFSafariViewController(url: url) self.show(vc, sender: false) }