如何在 iOS 14 Widget 中的 Provider 结构中使用 @FetchRequest 数据

问题描述

我目前正在使用 SwiftUI 开发应用程序。

我正在尝试使用 timer AppCore Data 开发 iOS 14 Widget

我想在小部件中 00:00 中的持续时间值为 Core Data显示 0.0。 所以我参考这篇文章SwiftUI iOS 14 Widget CountDown

在本文中,我必须使用从 struct Provider: TimelineProvider 中的 Core Data 获取的数据。

但是当我在 @FetchRequest 中使用 struct Provider: TimelineProvider 声明一个变量时,Core Data 中的数据永远不会显示。 (// display_A 在我附在下面的代码中)

@FetchRequest 中使用 struct TimerWidgetEntryView : View 的情况下,数据显示良好。 (// display_B 在我附在下面的代码中)

这是我的小部件的屏幕截图

enter image description here

我的目标是在我的代码中同时在 20.0display_A显示 display_B

我怎么能这样做?


代码如下:

import WidgetKit
import SwiftUI
import CoreData

struct Provider: TimelineProvider {
    
    var moc = PersistenceController.shared.managedobjectContext
    
    init(context : NSManagedobjectContext) {
        self.moc = context
    }
    
    @FetchRequest(entity: TimerEntity.entity(),sortDescriptors: [NSSortDescriptor(
                                                                    key:"createdDate",ascending:true)],animation:.spring()) var timerEntity:FetchedResults<TimerEntity>
    
    func placeholder(in context: Context) -> SimpleEntry {
        return SimpleEntry(date: Date(),duration: timerEntity.first?.duration ?? 0.0)
    }
    
    func getSnapshot(in context: Context,completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(),duration: timerEntity.first?.duration ?? 0.0)
        return completion(entry)
    }
    
    func getTimeline(in context: Context,completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []
        
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .minute,value: hourOffset,to: currentDate)!
            let entry = SimpleEntry(date: entryDate,duration: timerEntity.first?.duration ?? 0.0)
            entries.append(entry)
        }
        
        let timeline = Timeline(entries: entries,policy: .atEnd)
        completion(timeline)
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let duration: Double
}

struct TimerWidgetEntryView : View {
    @FetchRequest(entity: TimerEntity.entity(),animation:.spring()) var timerEntity:FetchedResults<TimerEntity>
        
    var entry: Provider.Entry
    
    var body: some View {
        return (
            vstack{
                Text(String(entry.duration)) // display_A
                Text(String(timerEntity.first?.duration ?? 0.0)) // display_B
            }
        )
    }
}

@main
struct TimerWidget: Widget {
    let kind: String = "TimerWidget"
    
    var body: some WidgetConfiguration {
        StaticConfiguration(kind: kind,provider: Provider(context: PersistenceController.shared.managedobjectContext)) { entry in
            TimerWidgetEntryView(entry: entry)
                .environment(\.managedobjectContext,PersistenceController.shared.managedobjectContext)
        }
        .configurationdisplayName("My Widget")
    }
}

Xcode:版本 12.0.1

iOS:14.0

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)