Search code examples
iosswiftweather-apiweatherkit

How to use WeatherKit to fetch hourly temperature?


I am an attempting to fetch the hourly temperature forecast from WeatherKit; however, I keep receiving the error "Cannot assign value of type 'Forecast' to type '[HourWeather]'. I am receiving the error in the function updateHourlyWeather. The goal of fetching the hourly weather is to be able to use the hourly weather to make a line chart of the ambient temperature.

import SwiftUI
import CoreLocation
import WeatherKit
import Foundation

@MainActor
class WeatherData: ObservableObject {
static let shared = WeatherData()
private let service = WeatherService.shared
@Published var currentWeather: CurrentWeather?
@Published var hourlyForecast: [HourWeather] = []

func updateCurrentWeather(userLocation: CLLocation) {
    Task.detached(priority: .userInitiated) {
        do {
            let forcast = try await self.service.weather(
                for: userLocation,
                including: .current)
            DispatchQueue.main.async {
                self.currentWeather = forcast
            }
        } catch {
            print(error.localizedDescription)
        }
    }
}

func updateHourlyWeather(userLocation: CLLocation) {
    Task.detached(priority: .userInitiated) {
        do {
            let forcast = try await self.service.weather(
                for: userLocation,
                including: .hourly)
            DispatchQueue.main.async {
                self.hourlyForecast = forcast
            }
        } catch {
            print(error.localizedDescription)
        }
    }
}
}

struct LocalizedWeatherView: View {
@ObservedObject var weatherDataHelper = WeatherData.shared
@ObservedObject var userLocationHelper = WeatherLocationManager.shared
var body: some View {
    Form {
        if let currentWeather = weatherDataHelper.currentWeather {
            Section {
                Label(currentWeather.temperature.formatted(), systemImage: "thermometer")
                Label("\(Int(currentWeather.humidity * 100))%", systemImage: "humidity.fill")
                Label(currentWeather.isDaylight ? "Day time" : "Night time", systemImage: currentWeather.isDaylight ? "sun.max.fill" : "moon.stars.fill")
            } header: {
                HStack {
                    Spacer()
                    Image(systemName: currentWeather.symbolName)
                        .font(.system(size: 60))
                    Spacer()
                }
            }
        }
        Section {
            if userLocationHelper.userLocation == nil {
                Button("Load user current location") {
                    loadUserCurrentLocation()
                }
            }
            Button("Fetch current weather") {
                loadCurrentWeatherData()
            }
        }
    }
}

func loadUserCurrentLocation() {
    userLocationHelper.requestPermission()
    userLocationHelper.locationManager.requestLocation()
}

func loadCurrentWeatherData() {
    guard let userLocation = WeatherLocationManager.shared.userLocation else {
        return
    }
    Task.detached { @MainActor in
        weatherDataHelper.updateCurrentWeather(userLocation: userLocation)
    }
}
}

Solution

  • You should be using

    self.hourlyForecast = forcast.forecast
    

    https://developer.apple.com/documentation/weatherkit/forecast