You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Widget无法加载显示Core Data对象/属性问题求助

问题:Widget无法加载Core Data对象属性,仅能显示基础类型数据

已完成主应用与Widget Extension的Core Data文件共享、App Group配置:

  • Provider中可正常加载所有交易数据,计算出的总额(Double类型)能传入Widget视图并正常显示
  • 将交易数组传入Widget视图时,无法加载显示内容,仅能看到空矩形;但可确认数据是可访问的——颜色显示准确,数组计数也正确

相关代码

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

实际设备显示效果

设备显示效果

临时解决办法

目前只能通过在loadTransactions()中提取单个属性传入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
}

内容的提问来源于stack exchange,提问作者user17745324

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 09:48:13