Impossible to "unwrap" a var from WeatherKit in SwiftUI

68 views Asked by At

I'd like to "unwrap" the sunrise from dayWeather but I don't know what I use instead of "Something". I've tried many things without success. Xcode always tells me that "dayWeather is inaccessible". Do you know what can I use?

extension "Something" {
    public var unwrappedSunrise: Date {
        dayWeather.first?.sun.sunrise ?? Date()
    }
}

Here's the WeatherManager I've got from a nice dude on SO.

@MainActor
final class WeatherManager: ObservableObject {
    enum LoadingState {
        case idle
        case loading
        case loaded(CurrentWeather, Forecast<DayWeather>)
        case failed(Error)
    }

    @Published var loadingState: LoadingState = .idle

    init() {
        loadingState = .loading
        Task {
            await requestWeather()
        }
    }

    func requestWeather() async {
        let location = CLLocation(latitude: 48.856613, longitude: 2.352222) /* Paris, France */

        let nowDate = Date.now
        let sevenDaysFromDate = Calendar.current.date(byAdding: .day, value: 7, to: nowDate) ?? Date()

        let currentWeather: WeatherQuery = .current
        let dailyWeather: WeatherQuery = .daily(startDate: nowDate, endDate: sevenDaysFromDate)

        do {
            let (currentWeather, dayWeather) = try await WeatherService.shared.weather(for: location, including: currentWeather, dailyWeather)
            loadingState = .loaded(currentWeather, dayWeather)
        } catch {
            loadingState = .failed(error)
        }
    }
}

Thanks, in advance!

1

There are 1 answers

1
workingdog support Ukraine On BEST ANSWER

You could try something like this:

extension Forecast<DayWeather> {
    public var unwrappedSunrise: Date {
        self.forecast.first?.sun.sunrise ?? Date()
    }
} 

and call it like this

  let sunrise = dayWeather.unwrappedSunrise

but as mentioned this is hidden code, you are better off using

let sunrise = dayWeather.forecast.first?.sun.sunrise ?? Date()

then you know exactly what your code is doing.

You could also use a function (eg in your WeatherManager) such as:

func unwrappedSunrise(_ dayWeather: Forecast<DayWeather>) -> Date {
    dayWeather.forecast.first?.sun.sunrise ?? Date()
}

and call it like this inside WeatherManager:

  let sunrise = unwrappedSunrise(dayWeather)

or, outside

  let sunrise = weatherManager.unwrappedSunrise(dayWeather)