swift – iOS widget not updating when choosing SwiftData AppIntent

0
26
swift – iOS widget not updating when choosing SwiftData AppIntent


Swift hobbyist…Be happy to level out how unhealthy the code is.

I am making an attempt to construct a SwiftUI app and I’ve a SwiftData mannequin referred to as Diem (a countdown occasion class). The mannequin is linked to DynamicAppIntent in that the person ought to be capable to select from one of many countdowns within the mannequin to show on the widget.

After a lot trouble (Fetch from SwiftData mannequin for DynamicAppIntent Widget) the my question lastly stopped crashing. Nevertheless, the widget view just isn’t updating with the chosen AppIntent from SwiftData. I feel the issue may be with my Supplier? I nonetheless do not totally perceive how timeline works and updates. However it may additionally nonetheless be with my WidgetConfigurationIntent/defaultQuery

The complete challenge is on GitHub. Some excerpts beneath:

DiemEntityQuery.swift

struct DiemEntityQuery: EntityQuery, Sendable {
    func entities(for identifiers: [DiemEntity.ID]) async throws -> [DiemEntity] {
        logger.data("Loading diems for identifiers: (identifiers)")
        let container = attempt ModelContainer(for: Diem.self)
        let modelContext = ModelContext(container)
        let diems = attempt modelContext.fetch(FetchDescriptor(predicate: #Predicate { identifiers.incorporates($0.title) }))
//        let diems = attempt modelContext.fetch(FetchDescriptor())
        logger.data("Discovered (diems.depend) diems")
        return diems.map { DiemEntity(from: $0) }
    }
    
    func suggestedEntities() async throws -> [DiemEntity] {
        logger.data("Loading diems to counsel for particular diem...")
        let container = attempt ModelContainer(for: Diem.self)
        let modelContext = ModelContext(container)
        let diems = attempt modelContext.fetch(FetchDescriptor())
        logger.data("Discovered (diems.depend) diems")
        return diems.map { DiemEntity(from: $0) }
    }
}

DiemWidgetProvider.swift

personal let logger = Logger(subsystem: "Widgets", class: "DiemTimelineProvider")

struct DiemWidgetProvider: AppIntentTimelineProvider {
    let modelContext = ModelContext(attempt! ModelContainer(for: Diem.self))  // identical problem as Intent
    
    func placeholder(in context: Context) -> DiemWidgetEntry {
//        let diem = attempt! modelContext.fetch(FetchDescriptor(sortBy: [.init(.date)])).first!
        logger.data("Calling placeholder() in DiemWidgetProvider...")
        return DiemWidgetEntry(date: .now, diem: .placeholder)
    }

    func snapshot(for configuration: DiemWidgetIntent, in context: Context) async -> DiemWidgetEntry {
        let diems = attempt! modelContext.fetch(FetchDescriptor(sortBy: [.init(.date)]))
        logger.data("Discovered (diems.depend) diems")
        guard let diem = diems.first else {
            return DiemWidgetEntry(date: .now, diem: .placeholder)
        }
        return DiemWidgetEntry(date: .now, diem: diem)
    }
    
    func timeline(for configuration: DiemWidgetIntent, in context: Context) async -> Timeline {
        // TODO: replace widget as soon as per day

        // Use the chosen intent parameter to generate the timeline entry
        if let diemEntity = configuration.diem {
            logger.data("Discovered configuration diem: (diemEntity.title)")
            let diem = Diem(entity: diemEntity)
            let entry = DiemWidgetEntry(date: .now, diem: diem)
            let timeline = Timeline(entries: [entry], coverage: .atEnd)
            return timeline
        } else {
            // If no diem is chosen, present a placeholder or default entry
            let diems = attempt! modelContext.fetch(FetchDescriptor(sortBy: [.init(.date)]))
            logger.data("No diem chosen. Offering placeholder to widget...")
            logger.data("Discovered (diems.depend) diems")
            guard let diem = diems.first else {
                logger.data("Utilizing placeholder diem as placeholder")
                return Timeline(
                    entries: [DiemWidgetEntry(date: .now, diem: .placeholder)],
                    coverage: .by no means
                )
            }
            logger.data("Utilizing first diem as placeholder...")
            return Timeline(entries: [DiemWidgetEntry(date: .now, diem: diem)], coverage: .atEnd)
        }
    }
}

LEAVE A REPLY

Please enter your comment!
Please enter your name here