I've noticed a few problems when fetching hourly weather data. I'll state the issues, then provide my code. Let me know if I'm doing something wrong. It seems like a caching problem.
Issue 1: When fetching hourly data, the same results are returned for consecutive fetches with different dates, but same location. Problem goes away, if location is changed slightly. (comment out second location in code to see)
Issue 2: After running app, if dates are changed and app is re-run, the results from the original dates are returned. You have to delete the app from the device and re-run, to get new data.
I'm using macOS 12.6, Xcode 14.0, and iOS 16.0
import UIKit
import CoreLocation
import WeatherKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
Task {
do {
var location = CLLocation()
var startDate = Date()
location = CLLocation(latitude: 37.335, longitude: -122.009)
startDate = Calendar.current.date(byAdding: .day, value: -1, to: Date())! // yesterday
try await fetch(location: location, startDate: startDate)
location = CLLocation(latitude: 37.335, longitude: -122.008)
startDate = Calendar.current.date(byAdding: .day, value: 1, to: Date())! // tomorrow
try await fetch(location: location, startDate: startDate)
print("done")
} catch {
print(error)
}
}
}
private func fetch(location: CLLocation, startDate: Date) async throws {
// set endDate to startDate + 1 hour, to get two hourly points;
// WeatherKit will round both dates to prior whole hours;
// I intend to interpolate between the two points to get weather at the exact startDate (not shown)
let endDate = Calendar.current.date(byAdding: .hour, value: 1, to: startDate)!
print()
print("requested location: (\(location.coordinate.latitude), \(location.coordinate.longitude))")
print("requested times: \(dateStringFrom(date: startDate)), \(dateStringFrom(date: endDate))")
//-------------------------------------------------------
let hourlyWeather = try await WeatherService().weather(for: location, including: .hourly(startDate: startDate, endDate: endDate)).forecast
//-------------------------------------------------------
print("received times: \(hourlyWeather.indices.map { dateStringFrom(date: hourlyWeather[$0].date) }.joined(separator: ", "))")
print("received temps: \(hourlyWeather.indices.map { String(hourlyWeather[$0].temperature.converted(to: .fahrenheit).value) }.joined(separator: ", "))")
}
// convert from swift Date to "10/1/22, 6:46 PM"
private func dateStringFrom(date: Date) -> String {
let formatter = DateFormatter()
formatter.dateStyle = .short
formatter.timeStyle = .short
return formatter.string(from: date)
}
}