Skip to content

Instantly share code, notes, and snippets.

@Jimmy-Prime
Created July 26, 2024 08:27
Show Gist options
  • Select an option

  • Save Jimmy-Prime/354c1560fcdd9faefe012f91dd09afbb to your computer and use it in GitHub Desktop.

Select an option

Save Jimmy-Prime/354c1560fcdd9faefe012f91dd09afbb to your computer and use it in GitHub Desktop.
//
// 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