Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get different data for each widget

I'm reading up on WidgetBundle and having multiple Widgets - in my case I want to offer the user two different widgets based on gender. So the user can choose to see the Mens one and also the Womens one.

For each widget the timeline would need to call a different API - what's the best way to do this? I can't see any examples of having a WidgetBundle and modifying the timelines to be slightly different for each (it's literally a parameter in the api URL). Or is this not possible?

Code:

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")
    }
}
like image 490
vanilla_splsh Avatar asked Nov 17 '25 10:11

vanilla_splsh


1 Answers

You can pass the gender parameter to the Provider so it can be used later in the getTimeline function:

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)
    }
}

Then, you only need to pass the correct parameter to the 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")
    }
}
like image 149
pawello2222 Avatar answered Nov 19 '25 10:11

pawello2222



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!