I'm currently testing my Swift skills while having fun with WeatherKit but there's something I can't do by myself.
I'd like to "unwrap" the temperature.value I get from hour like I did for currenWeather? Is it possible, if yes, what should I do?
import Foundation
import WeatherKit
class WeatherManager: ObservableObject {
@Published private var currentWeather: CurrentWeather?
@Published private var hourWeather: Forecast<HourWeather>?
var isLoading: Bool
init() {
isLoading = true
Task {
await getWeather(48.864716, 2.349014) /* Paris, France */
}
}
@MainActor
func getWeather(_ lat: Double, _ long: Double) async {
let nowDate = Date.now
let oneDayFromDate = Date.now.addingTimeInterval(60 * 60 * 24)
do {
currentWeather = try await WeatherService.shared.weather(for: .init(latitude: lat, longitude: long), including: .current)
hourWeather = try await WeatherService.shared.weather(for: .init(latitude: lat, longitude: long), including: .hourly(startDate: nowDate, endDate: oneDayFromDate))
} catch {
print("WeatherKit failed to get: \(error)")
}
isLoading = false
}
var unwrappedTemperature: Double {
// Here: it's unwrapped
currentWeather?.temperature.value ?? 0
}
var unwrappedHourly: [HourWeather] {
hourWeather?.forecast ?? []
}
}
import SwiftUI
struct ContentView: View {
@EnvironmentObject private var weatherManager: WeatherManager
var body: some View {
VStack {
if !weatherManager.isLoading {
Text("\(weatherManager.unwrappedTemperature, specifier: "%.0f")°C")
ScrollView(.horizontal, showsIndicators: false) {
HStack {
ForEach(weatherManager.unwrappedHourly, id: \.date) { hour in
// Here: is it possible to unwrap "temperature.value"?
Text("\(hour.temperature.value, specifier: "%.0f")°C")
}
}
}
} else {
ProgressView()
}
}
}
}
I hope my question is clear enough. Thanks, in advance!
WeatherKituses non-optional values as much as possible.A better approach is to create an enum for the loading state and set it accordingly. There are states for
idle,loading,loadedpassing the non-optional data andfailedpassing the error.And it's not necessary to call the service twice.
In the view
switchon the state and show appropriate views