Apple Watch Complication首次添加显示空白问题求助
问题:Apple Watch Complication首次添加空白,打开应用后恢复正常
我正在开发一款带有Apple Watch Complication的应用。首次将Complication添加到表盘时,它会保持空白状态;点击该Complication打开应用,关闭应用后表盘上的Complication才会正常显示。在同一表盘或其他表盘添加第二个Complication时,新添加的和原有的Complication都会正常显示。请问这是我的Timeline Provider存在问题,还是API调用耗时过长导致的?
初始Provider代码
import WidgetKit import CoreLocation struct Provider: TimelineProvider { let locationManager = LocationManager() func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: .now, station: .placeholder, recentMeasurements: []) } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { if context.isPreview { let station = Station.placeholder let recentMeasurements = Station.measurmentsPlaceholder let entry = SimpleEntry(date: .now, station: station, recentMeasurements: recentMeasurements) completion(entry) } else { Task { let station = await APIService.getStations().first! let recentMeasurements = await APIService.getStationMeasurements(station: station, days: 7) let entry = SimpleEntry(date: .now, station: station, recentMeasurements: recentMeasurements) completion(entry) } } } func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> ()) { Task { let stations = await APIService.getStations() let station = locationManager.getNearestStation(in: stations) ?? stations.first! let recentMeasurements = await APIService.getStationMeasurements(station: station, days: 7) let entry = SimpleEntry(date: .now, station: station, recentMeasurements: recentMeasurements) let secondEntry = SimpleEntry(date: .now.advanced(by: 60 * 30), station: station, recentMeasurements: recentMeasurements) let timeline = Timeline(entries: [entry, secondEntry], policy: .atEnd) completion(timeline) } } }
编辑(2023.02.18):使用Result的Provider版本
import WidgetKit import CoreLocation struct Provider: TimelineProvider { let locationManager = LocationManager() func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: .now, station: .success(Station.placeholder), recentMeasurements: .success([])) } func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { if context.isPreview { let entry = SimpleEntry(date: .now, station: .success(Station.placeholder), recentMeasurements: .success(Station.measurmentsPlaceholder)) completion(entry) } else { Task { guard let stations = try? await APIService.getStations(), let station = stations.first else { completion(SimpleEntry(date: .now, station: .failure(ProviderError.stationFetch), recentMeasurements: .failure(ProviderError.stationFetch))) return } guard let recentMeasurements = try? await APIService.getStationMeasurements(station: station, days: 7) else { completion(SimpleEntry(date: .now, station: .failure(ProviderError.measurementsFetch), recentMeasurements: .failure(ProviderError.measurementsFetch))) return } let entry = SimpleEntry(date: .now, station: .success(station), recentMeasurements: .success(recentMeasurements)) completion(entry) } } } func getTimeline(in context: Context, completion: @escaping (Timeline<SimpleEntry>) -> ()) { Task { let stationResult: Result<Station, Error> let station: Station? if let stations = try? await APIService.getStations() { station = locationManager.getNearestStation(in: stations) ?? stations.first! stationResult = .success(station!) } else { station = nil stationResult = .failure(ProviderError.stationFetch) } let recentMeasurements: Result<[Measurement], Error> if let result = try? await APIService.getStationMeasurements(station: station!, days: 7) { recentMeasurements = .success(result) } else { recentMeasurements = .failure(ProviderError.measurementsFetch) } let entry = SimpleEntry(date: .now, station: stationResult, recentMeasurements: recentMeasurements) let secondEntry = SimpleEntry(date: .now.advanced(by: 60 * 30), station: stationResult, recentMeasurements: recentMeasurements) let timeline = Timeline(entries: [entry, secondEntry], policy: .atEnd) completion(timeline) } } } enum ProviderError: Error { case stationFetch case measurementsFetch }
数据获取函数
static func getJSON<T: Decodable>(from path: String) async throws -> [T] { guard let url = URL(string: path) else { return [] } let (data, _) = try await URLSession.shared.data(from: url) let collection = try JSONDecoder().decode([T].self, from: data) return collection }
内容的提问来源于Stack Exchange,提问作者Jonas Lang
相关产品推荐
相关产品推荐

