Files
aris-old/IrisCompanion/iris/ViewModels/CandidatesViewModel.swift
2026-01-08 19:16:32 +00:00

72 lines
2.7 KiB
Swift

//
// CandidatesViewModel.swift
// iris
//
// Created by Codex.
//
import CoreLocation
import Foundation
import os
@MainActor
final class CandidatesViewModel: ObservableObject {
@Published private(set) var candidates: [Candidate] = []
@Published private(set) var lastUpdatedAt: Date? = nil
@Published private(set) var isLoading = false
@Published private(set) var lastError: String? = nil
@Published private(set) var diagnostics: [String: String] = [:]
var demoLatitude: Double = 51.5074
var demoLongitude: Double = -0.1278
private let logger = Logger(subsystem: Bundle.main.bundleIdentifier ?? "iris", category: "CandidatesViewModel")
func refresh() {
guard !isLoading else { return }
isLoading = true
lastError = nil
diagnostics = [:]
let location = CLLocation(latitude: demoLatitude, longitude: demoLongitude)
let now = Int(Date().timeIntervalSince1970)
logger.info("Refresh start lat=\(self.demoLatitude, format: .fixed(precision: 4)) lon=\(self.demoLongitude, format: .fixed(precision: 4)) now=\(now)")
Task {
defer {
Task { @MainActor in
self.isLoading = false
self.lastUpdatedAt = Date()
}
}
if #available(iOS 16.0, *) {
let ds = WeatherDataSource()
let result = await ds.candidatesWithDiagnostics(for: location, now: now)
await MainActor.run {
self.candidates = result.candidates.sorted { $0.confidence > $1.confidence }
self.diagnostics = result.diagnostics
if let error = result.weatherKitError {
self.lastError = "WeatherKit error: \(error)"
}
}
if let error = result.weatherKitError {
self.logger.error("WeatherKit error: \(error)")
}
self.logger.info("Produced candidates count=\(result.candidates.count)")
for c in result.candidates {
self.logger.info("Candidate id=\(c.id, privacy: .public) type=\(c.type.rawValue, privacy: .public) conf=\(c.confidence, format: .fixed(precision: 2)) ttl=\(c.ttlSec) title=\(c.title, privacy: .public)")
}
if result.candidates.isEmpty {
self.logger.info("Diagnostics: \(String(describing: result.diagnostics), privacy: .public)")
}
} else {
await MainActor.run {
self.candidates = []
self.lastError = "WeatherKit requires iOS 16+."
}
}
}
}
}