如何为每个小部件获取不同的数据
How to get different data for each widget
我正在阅读 WidgetBundle
并拥有多个小部件 - 在我的例子中,我想根据性别为用户提供两个不同的小部件。因此,用户可以选择查看 Mens 和 Womens。
对于每个小部件,时间轴需要调用不同的 API - 执行此操作的最佳方法是什么?我看不到任何具有 WidgetBundle
并将时间线修改为 略微 的示例(它实际上是 api [=27 中的一个参数) =]).或者这是不可能的?
代码:
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
// Call API here and get gifts
// I'd want to set "womens" or "mens" in the api url here depending on the widget
let entry = WidgetTimelineEntry(date: Date(), gifts: gifts, widgetURL: widgetURL)
let date = Calendar.current.date(byAdding: .minute, value: 30, to: Date())!
let timeline = Timeline(entries: [entry], policy: TimelineReloadPolicy.after(date))
completion(timeline)
}
...
struct WidgetTimelineEntry: TimelineEntry {
let date: Date
let gifts: [Product]
let widgetURL: URL
}
struct GiftWidgetEntryView : View {
@Environment(\.widgetFamily) private var widgetFamily
var entry: Provider.Entry
var body: some View {
Group {
if widgetFamily == .systemMedium {
MediumWidgetView(gifts: entry.gifts)
}
}
.widgetURL(entry.widgetURL)
}
}
@main
struct GiftWidgets: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
// My widgets
WomensWidget()
MensWidget()
}
}
struct WomensWidget: Widget {
let kind: String = "WomensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Women's Gift Widget")
.description("See some womens gift ideas")
}
}
struct MensWidget: Widget {
let kind: String = "MensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Men's Gift Widget")
.description("See some mens gift ideas")
}
}
您可以将 gender
参数传递给 Provider
以便稍后在 getTimeline
函数中使用它:
enum Gender {
case male, female // ...
}
struct Provider: TimelineProvider {
let gender: Gender
...
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
// Configure the API call based on the `gender` property
let entry = WidgetTimelineEntry(date: Date(), gifts: gifts, widgetURL: widgetURL)
let date = Calendar.current.date(byAdding: .minute, value: 30, to: Date())!
let timeline = Timeline(entries: [entry], policy: TimelineReloadPolicy.after(date))
completion(timeline)
}
}
然后,你只需要将正确的参数传递给 Provider
:
struct WomensWidget: Widget {
let kind: String = "WomensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(gender: .female)) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Women's Gift Widget")
.description("See some womens gift ideas")
}
}
struct MensWidget: Widget {
let kind: String = "MensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(gender: .male)) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Men's Gift Widget")
.description("See some mens gift ideas")
}
}
我正在阅读 WidgetBundle
并拥有多个小部件 - 在我的例子中,我想根据性别为用户提供两个不同的小部件。因此,用户可以选择查看 Mens 和 Womens。
对于每个小部件,时间轴需要调用不同的 API - 执行此操作的最佳方法是什么?我看不到任何具有 WidgetBundle
并将时间线修改为 略微 的示例(它实际上是 api [=27 中的一个参数) =]).或者这是不可能的?
代码:
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
// Call API here and get gifts
// I'd want to set "womens" or "mens" in the api url here depending on the widget
let entry = WidgetTimelineEntry(date: Date(), gifts: gifts, widgetURL: widgetURL)
let date = Calendar.current.date(byAdding: .minute, value: 30, to: Date())!
let timeline = Timeline(entries: [entry], policy: TimelineReloadPolicy.after(date))
completion(timeline)
}
...
struct WidgetTimelineEntry: TimelineEntry {
let date: Date
let gifts: [Product]
let widgetURL: URL
}
struct GiftWidgetEntryView : View {
@Environment(\.widgetFamily) private var widgetFamily
var entry: Provider.Entry
var body: some View {
Group {
if widgetFamily == .systemMedium {
MediumWidgetView(gifts: entry.gifts)
}
}
.widgetURL(entry.widgetURL)
}
}
@main
struct GiftWidgets: WidgetBundle {
@WidgetBundleBuilder
var body: some Widget {
// My widgets
WomensWidget()
MensWidget()
}
}
struct WomensWidget: Widget {
let kind: String = "WomensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Women's Gift Widget")
.description("See some womens gift ideas")
}
}
struct MensWidget: Widget {
let kind: String = "MensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider()) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Men's Gift Widget")
.description("See some mens gift ideas")
}
}
您可以将 gender
参数传递给 Provider
以便稍后在 getTimeline
函数中使用它:
enum Gender {
case male, female // ...
}
struct Provider: TimelineProvider {
let gender: Gender
...
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
// Configure the API call based on the `gender` property
let entry = WidgetTimelineEntry(date: Date(), gifts: gifts, widgetURL: widgetURL)
let date = Calendar.current.date(byAdding: .minute, value: 30, to: Date())!
let timeline = Timeline(entries: [entry], policy: TimelineReloadPolicy.after(date))
completion(timeline)
}
}
然后,你只需要将正确的参数传递给 Provider
:
struct WomensWidget: Widget {
let kind: String = "WomensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(gender: .female)) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Women's Gift Widget")
.description("See some womens gift ideas")
}
}
struct MensWidget: Widget {
let kind: String = "MensWidget"
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: Provider(gender: .male)) { entry in
GiftWidgetEntryView(entry: entry)
}
.configurationDisplayName("Men's Gift Widget")
.description("See some mens gift ideas")
}
}