11.5 C
London
Thursday, April 25, 2024

ios – Utilizing WeatherKit SunEvents


I’m making an attempt to make use of weatherKit to get the dawn and sundown in order that I can change the WeatherConditionIcons relying upon if the time is earlier than or after dawn and sundown. Initially I used to be simply getting day time icons however not I’m solely receiving night time time icons. I used a debugging line to get the dawn and sundown time to print. Nonetheless, the dawn and sundown time are printing that they’re occurring 4 hours after the precise dawn and sundown. Right here is the code I’ve proper now:

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

    @Revealed var cityName: String = ""

    @Revealed var sunEvents: SunEvents?

    func updateWeather(for location: CLLocation) {
        Job {
             do {
                 let currentForecast = attempt await service.climate(for: location, together with: .present)
            await MainActor.run {
                self.currentWeather = currentForecast
            }

            let dailyForecast = attempt await service.climate(for: location, together with: .each day)
            await MainActor.run {
                self.dailyForecast = dailyForecast.forecast
                if let firstDayWeather = dailyForecast.forecast.first {
                    self.sunEvents = firstDayWeather.solar
                }
            }
        } catch {
            print("Didn't fetch climate information: (error)")
        }
    }
}
}

struct HourlyForecastView: View {
@ObservedObject var weatherData: WeatherData

var physique: some View {
   VStack {
       if let startDate = weatherData.hourlyForecast.first?.date, let endDate = weatherData.hourlyForecast.final?.date {
           HStack {
               Textual content("(formatDate(startDate)) to (formatDate(endDate))")
                   .font(.caption)
           }
           .padding([.leading, .trailing])
       }
       ScrollView(.horizontal, showsIndicators: false) {
           HStack(spacing: 20) {
               ForEach(weatherData.hourlyForecast, id: .date) { hourWeather in
                   VStack(spacing: 5) {
                       Textual content(hourWeatherFormatter.string(from: hourWeather.date))
                           .font(.caption)
                       
                       Picture(systemName: weatherData.getWeatherConditionIcon(for: hourWeather.situation, at: hourWeather.date))
                           .foregroundColor(.blue)
                       
                       Textual content("(hourWeather.precipitationChance * 100, specifier: "%.0f%%")")
                           .font(.caption)
                           .foregroundColor(.blue)
                       
                       Textual content("(hourWeather.temperature.worth, specifier: "%.1f°")")
                           .font(.caption)
                   }
                   .body(width: 40, top: 105)
               }
           }
           .background(RoundedRectangle(cornerRadius: 7).fill(Coloration.grey.opacity(0.2)))
       }
   }
}

personal var hourWeatherFormatter: DateFormatter {
   let formatter = DateFormatter()
   formatter.dateFormat = "ha"
   formatter.amSymbol = "AM"
   formatter.pmSymbol = "PM"
   return formatter
}

 personal func formatDate(_ date: Date) -> String {
    let formatter = DateFormatter()
    formatter.dateStyle = .medium
    return formatter.string(from: date)
 }
}

extension WeatherData {
func getWeatherConditionIcon(for situation: WeatherCondition, at time: Date) -> String {
      guard let sunEvents = dailyForecast.first?.solar else {
          print("No SunEvents information accessible, defaulting to daytime icons.")
          return getDefaultIcon(for: situation, isDaytime: true)
      }

      print("Dawn: (String(describing: sunEvents.dawn)), Sundown: (String(describing: sunEvents.sundown)), Present Time: (time)")

      let isDaytime: Bool
      if let dawn = sunEvents.dawn, let sundown = sunEvents.sundown {
          isDaytime = time >= dawn && time <= sundown
      } else {
          isDaytime = true
      }

      return getDefaultIcon(for: situation, isDaytime: isDaytime)
  }

personal func getDefaultIcon(for situation: WeatherCondition, isDaytime: Bool) -> String {
    change situation {
    case .clear:
        return isDaytime ? "solar.max.fill" : "moon.stars.fill"
    case .cloudy:
        return "cloud.fill"
    case .drizzle, .rain:
        return isDaytime ? "cloud.drizzle.fill" : "cloud.drizzle.fill.bolt"
    case .snow:
        return "snow"
    case .sleet:
        return "cloud.sleet.fill"
    case .hail:
        return "cloud.hail.fill"
    case .thunderstorms, .scatteredThunderstorms, .strongStorms:
        return "cloud.bolt.rain.fill"
    case .foggy:
        return "cloud.fog.fill"
    case .partlyCloudy:
        return isDaytime ? "cloud.solar.fill" : "cloud.moon.fill"
    case .mostlyCloudy:
        return "cloud.fill"
    case .mostlyClear:
        return isDaytime ? "solar.max.fill" : "moon.stars.fill"
    case .windy, .breezy:
        return "wind"
    case .smoky:
        return "smoke.fill"
    case .haze:
        return isDaytime ? "solar.haze.fill" : "moon.haze.fill"
    case .blowingDust:
        return "solar.mud.fill"
    case .heavyRain:
        return "cloud.heavyrain.fill"
    case .sunShowers:
        return isDaytime ? "solar.rain.fill" : "moon.rain.fill"
    case .isolatedThunderstorms:
        return "cloud.bolt.rain.fill"
    case .tropicalStorm, .hurricane:
        return "hurricane"
    case .blizzard, .blowingSnow, .heavySnow:
        return "snowflake"
    case .frigid:
        return "thermometer.snowflake"
    case .sizzling:
        return "thermostat.solar"
    case .wintryMix:
        return "cloud.snow.fill"
    default:
        return "questionmark.circle.fill"
    }
}
}

Latest news
Related news

LEAVE A REPLY

Please enter your comment!
Please enter your name here