1 创建widget extension
2 创建完成之后 理论上就可以运行了
关键代码包括 TimelineProvider TimelineEntry
正常代码是下面这样的
js
//
// home_widget_study.swift
// home_widget_study
//
// Created by gy on 2025/3/7.
//
import WidgetKit
import SwiftUI
struct Provider: TimelineProvider {
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), emoji: "😀")
}
func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), emoji: "😀")
completion(entry)
}
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, emoji: "😀")
entries.append(entry)
}
//entries 定义了刷新的时间 这里数组长度为5 每个元素的时间相差一小时 意思就是从小组件添加之后一小时刷新一次 好像这个时间不能设置的太短 最短好像是5分钟
let timeline = Timeline(entries: entries, policy: .atEnd)
completion(timeline)
}
// func relevances() async -> WidgetRelevances<Void> {
// // Generate a list containing the contexts this widget is relevant in.
// }
}
//里面的属性可以根据自己的需求 自定义
//但是这个date 好像是必须的 意思是下次刷新的时间 因为小组件不会自己刷新
struct SimpleEntry: TimelineEntry {
let date: Date
let emoji: String
}
struct home_widget_studyEntryView : View {
var entry: Provider.Entry
var body: some View {
VStack {
Text("Time:")
Text(entry.date, style: .time)
Text("Emoji:")
Text(entry.emoji)
}
}
}
struct home_widget_study: Widget {
let kind: String = "home_widget_study"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
if #available(iOS 17.0, *) {
home_widget_studyEntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
} else {
home_widget_studyEntryView(entry: entry)
.padding()
.background()
}
}
.configurationDisplayName("My Widget")
.description("This is an example widget.")
}
}
#Preview(as: .systemSmall) {
home_widget_study()
} timeline: {
SimpleEntry(date: .now, emoji: "😀")
SimpleEntry(date: .now, emoji: "🤩")
}
如果你的TimerLineProvider初始代码如下,运行会报错。你可以参考上面的代码修改调整一下。下面的代码好像是高版本的写法。
js
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(),model: 0)
}
func snapshot(for configuration: ConfigurationAppIntent, in context: Context) async -> SimpleEntry {
SimpleEntry(date: Date(), configuration: configuration,model: "456")
}
func timeline(for configuration: ConfigurationAppIntent, in context: Context) async -> Timeline<SimpleEntry> {
var entries: [SimpleEntry] = []
print("timelinetimelinetimelinetimelinetimeline===================")
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
let userdefaults = UserDefaults(suiteName: "group.com.aiintelligent.iossoftware.homewidget")
let model = userdefaults?.string(forKey: "model") ?? "model"
let a = print("==========model===",model)
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .minute, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate,model: model)
entries.append(entry)
}
return Timeline(entries: entries, policy: .atEnd)
}
如果你的widget body 是如下代码 也参照上面的修改 这个好像也是高版本代码
js
var body: some WidgetConfiguration {
AppIntentConfiguration(kind: kind, intent: ConfigurationAppIntent.self, provider: Provider()) { entry in
1EntryView(entry: entry)
.containerBackground(.fill.tertiary, for: .widget)
}
}
3 主动刷新小组件
js
WidgetCenter.shared.reloadTimelines(ofKind: "home_widget_study")
ofKind 在这里
4 主程序与小组件之间通信 传递数据
group_name 需要在开发者后台配置 在小组件 跟 主程序使用的group_name一定要一样,切必须是开发者后台配置的值。
js
var userdefaults = UserDefaults(suiteName: "group_name")