0

I am unable to feed and read core data objects/properties into my Widget view. I am only able to feed and present it Doubles/Strings beforehand and it will work.

Prior to this, I have made sure all Core Data related files are shared between both the Widget Extension and the main app. The App Group has been set up and the data can be loaded (I am able to load all transactions in the Provider, calculate the total, and feed that double into the Widget view).

However, when it comes to actually feeding an array of transactions into the Widget View, the data cannot be loaded and all I see are empty rectangles. However, I'm pretty certain the data is accessible as the colours are accurate, and if I display the count of the array, it is accurate too. Below is my attached code.

struct RecentExpenditureWidget: Widget {
    let kind: String = "ExpenditureWidget"

    var body: some WidgetConfiguration {
        
        IntentConfiguration(kind: kind, intent: RecentWidgetConfigurationIntent.self, provider: Provider()) { entry in
            ExpenditureWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("Recent Transactions")
        .description("View your latest expenses.")
        .supportedFamilies([.systemSmall])
    }
}

struct Provider: IntentTimelineProvider {
    typealias Intent = RecentWidgetConfigurationIntent
    
    public typealias Entry = RecentWidgetEntry
    
    func placeholder(in context: Context) -> RecentWidgetEntry {
    
        RecentWidgetEntry(date: Date(), amount: loadAmount(type: .week), transactions: loadTransactions(type: .week, count: 3))
    }

    func getSnapshot(for configuration: RecentWidgetConfigurationIntent, in context: Context, completion: @escaping (RecentWidgetEntry) -> ()) {
        
        

        let entry = RecentWidgetEntry(date: Date(), amount: loadAmount(type: configuration.duration), transactions: loadTransactions(type: configuration.duration, count: 3))
        completion(entry)
    }

    func getTimeline(for configuration: RecentWidgetConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {


        let entry = RecentWidgetEntry(date: Date(), amount: loadAmount(type: configuration.duration), transactions: loadTransactions(type: configuration.duration, count: 3))
        
        let timeline = Timeline(entries: [entry], policy: .atEnd)
        
        completion(timeline)
    }
    
    func loadAmount(type: TimePeriod) -> Double {
        let dataController = DataController()
        let itemRequest = dataController.fetchRequestForRecentTransactions(type: type)
        let transactions = dataController.results(for: itemRequest)
        
        
        var holdingTotal = 0.0
        
        transactions.forEach { transaction in
            holdingTotal += transaction.wrappedAmount
        }
        
        return holdingTotal
    }
    
    func loadTransactions(type: TimePeriod, count: Int) -> [Transaction] {
        let dataController = DataController()
        let itemRequest = dataController.fetchRequestForRecentTransactionsWithCount(type: type, count: count)
        return dataController.results(for: itemRequest)
    }
}

struct RecentWidgetEntry: TimelineEntry {
    let date: Date
    let amount: Double
    let transactions: [Transaction]
}

struct ExpenditureWidgetEntryView : View {
    let entry: Provider.Entry
    
    var body: some View {
        
        VStack(spacing: 5) {
            ForEach(entry.transactions) { transaction in
                HStack(spacing: 2) {
                    Capsule()
                        .fill(Color(transaction.category?.wrappedColour ?? ""))
                        .frame(width: 4)
                    
                    Text(transaction.wrappedNote)
                        .lineLimit(1)
                        .font(.system(size: 12, weight: .regular, design: .rounded))
                        .foregroundColor(Color.PrimaryText)
                    
                    
                    Text(transaction.amount, format: .currency(code: Locale.current.currencyCode ?? "USD"))
                        .font(.system(size: 12, weight: .regular, design: .rounded))
                        .foregroundColor(Color.SubtitleText)
                }
                .frame(height: 15)
            }
        }
        .padding(15)
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(Color.PrimaryBackground)
    }
}

This is the result I get on my actual devices:

enter image description here

The only (by extremely dumb) workaround I have found is to extract each property of a transaction in the loadTransaction() function, and then feed it into the Widget.

func loadTransactions(type: TimePeriod, count: Int) -> String {
    let dataController = DataController()
    let itemRequest = dataController.fetchRequestForRecentTransactionsWithCount(type: type, count: count)
    return dataController.results(for: itemRequest).first!.wrappedNote
}
  • Welcome to SO - Please take the [tour](https://stackoverflow.com/tour) and read [How to Ask](https://stackoverflow.com/help/how-to-ask) to improve, edit and format your questions. Without a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) it is impossible to help you troubleshoot. – lorem ipsum Aug 13 '22 at 11:37
  • You haven't given us enough information to diagnose the issue(s), so I will direct you to [this answer](https://stackoverflow.com/a/63945538/7129318) that gives a lot of links, including to @pawello2222 GitHub widgets examples which is very useful. Good luck. – Yrb Aug 13 '22 at 13:22

0 Answers0