Created
July 26, 2024 08:27
-
-
Save Jimmy-Prime/354c1560fcdd9faefe012f91dd09afbb to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // CatWidget.swift | |
| // WidgetCollection | |
| // | |
| // Created by 李昇輯 on 2024/7/25. | |
| // | |
| import AppIntents | |
| import SwiftUI | |
| import WidgetKit | |
| struct CatWidgetIntent: WidgetConfigurationIntent { | |
| static let title: LocalizedStringResource = "CatWidgetIntent" | |
| @Parameter(title: "Bucket", default: "0") | |
| var bucket: String | |
| } | |
| struct CatEntry: TimelineEntry { | |
| let date: Date | |
| let url: String | |
| let isSample: Bool | |
| let configuration: CatWidgetIntent | |
| } | |
| extension CatEntry { | |
| static let sample = CatEntry(date: .now, url: "https://cdn2.thecatapi.com/images/1p2.jpg", isSample: true, configuration: CatWidgetIntent()) | |
| } | |
| struct CatWidgetProvider: AppIntentTimelineProvider { | |
| func placeholder(in context: Context) -> CatEntry { | |
| CatEntry.sample | |
| } | |
| func snapshot(for configuration: CatWidgetIntent, in context: Context) async -> CatEntry { | |
| CatEntry(date: .now, url: "https://cdn2.thecatapi.com/images/1p2.jpg", isSample: true, configuration: configuration) | |
| } | |
| func timeline(for configuration: CatWidgetIntent, in context: Context) async -> Timeline<CatEntry> { | |
| // https://api.thecatapi.com/v1/images/search | |
| // [{"id":"1p2","url":"https://cdn2.thecatapi.com/images/1p2.jpg","width":500,"height":333}] | |
| struct CatApiResponse: Codable { | |
| let url: String | |
| } | |
| guard let (data, _) = try? await URLSession.shared.data(from: URL(string: "https://api.thecatapi.com/v1/images/search")!), | |
| let response = try? JSONDecoder().decode([CatApiResponse].self, from: data), | |
| let url = response.first?.url else { | |
| return Timeline(entries: [.sample], policy: .never) | |
| } | |
| let entry = CatEntry(date: .now, url: url, isSample: false, configuration: configuration) | |
| return Timeline(entries: [entry], policy: .after(entry.date.advanced(by: 86400))) | |
| } | |
| } | |
| struct CatWidget: Widget { | |
| let kind = "CatWidget" | |
| var body: some WidgetConfiguration { | |
| AppIntentConfiguration(kind: kind, intent: CatWidgetIntent.self, provider: CatWidgetProvider()) { entry in | |
| CatEntryView(entry: entry) | |
| .containerBackground(.fill.tertiary, for: .widget) | |
| } | |
| .configurationDisplayName("可愛貓貓圖") | |
| .description("thecatapi 提供的隨機貓貓圖片") | |
| .contentMarginsDisabled() | |
| } | |
| } | |
| struct CatEntryView: View { | |
| let entry: CatEntry | |
| var body: some View { | |
| Image(uiImage: uiImage) | |
| .resizable() | |
| .aspectRatio(contentMode: .fill) | |
| } | |
| private var uiImage: UIImage { | |
| let uiImage = UIImage(data: try! Data(contentsOf: URL(string: entry.url)!))! | |
| return uiImage.images?.first ?? uiImage | |
| } | |
| } | |
| #Preview(as: .systemLarge) { | |
| CatWidget() | |
| } timeline: { | |
| CatEntry.sample | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment