Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use fetch data in Intent Handler for editing Widget iOS 14?

I'm currently developing an application using SwiftUI.

I'm trying to make a widget user can edit some data using IntentConfiguration

I want to use some fetch data from CoreData in IntentHandler class for editing the widget like the image below.

enter image description here

I tried to make some codes but They don't work...

How could I solve my codes?


Here are the codes:

IntentHandler.swift

import WidgetKit
import SwiftUI
import CoreData
import Intents

class IntentHandler: INExtension, ConfigurationIntentHandling {
    
    var moc = PersistenceController.shared.managedObjectContext

    var timerEntity_0:TimerEntity?
    var timerEntity_1:TimerEntity?
    var timerEntity_2:TimerEntity?

    init(context : NSManagedObjectContext) {
        self.moc = context

        let request = NSFetchRequest<TimerEntity>(entityName: "TimerEntity")

        do{
            let result = try moc.fetch(request)
            timerEntity_0 = result[0]
            timerEntity_1 = result[1]
            timerEntity_2 = result[2]
        }
        catch let error as NSError{
            print("Could not fetch.\(error.userInfo)")
        }
    }
   
    func provideNameOptionsCollection(for intent: ConfigurationIntent, searchTerm: String?, with completion: @escaping (INObjectCollection<NSString>?, Error?) -> Void) {
        
        let nameIdentifiers:[NSString] = [
            NSString(string: timerEntity_0?.task ?? "default"),
            NSString(string: timerEntity_1?.task ?? "default"),
            NSString(string: timerEntity_2?.task ?? "default")
            // "meeting",
            // "cooking",
            // "shoping"
        ]
        let allNameIdentifiers = INObjectCollection(items: nameIdentifiers)
        
        completion(allNameIdentifiers,nil)
    }
    
    override func handler(for intent: INIntent) -> Any {
        
        return self
    }
}

Widget.swift

import WidgetKit
import SwiftUI
import Intents

struct Provider: IntentTimelineProvider {
    
    typealias Intent = ConfigurationIntent
    
    func placeholder(in context: Context) -> SimpleEntry {
        SimpleEntry(date: Date(), configuration: ConfigurationIntent(), name: "")
    }

    func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
        let entry = SimpleEntry(date: Date(), configuration: configuration, name: "")
        completion(entry)
    }

    func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        var entries: [SimpleEntry] = []

        // Generate a timeline consisting of five entries an hour apart, starting from the current date.
        let currentDate = Date()
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
            let entry = SimpleEntry(date: entryDate, configuration: configuration, name: configuration.Name ?? "")
            entries.append(entry)
        }

        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}

struct SimpleEntry: TimelineEntry {
    let date: Date
    let configuration: ConfigurationIntent
    var name:String
}

struct TimerIntentWidgetEntryView : View {
    var entry: Provider.Entry

    var body: some View {
        Text(entry.name)
            .font(.title)
        Text(entry.date, style: .time)
    }
}

@main
struct TimerIntentWidget: Widget {
    let kind: String = "TimerIntentWidget"

    var body: some WidgetConfiguration {
        IntentConfiguration(kind: kind, intent: ConfigurationIntent.self, provider: Provider()) { entry in
            TimerIntentWidgetEntryView(entry: entry)
        }
        .configurationDisplayName("My Widget")
        .description("This is an example widget.")
    }
}

tWidget.intentdefinition enter image description here


Xcode: Version 12.0.1

iOS: 14.0

Life Cycle: SwiftUI App

like image 751
Tio Avatar asked Oct 15 '25 01:10

Tio


1 Answers

I could display a list in the widget using fetch data from CoreData like the code below:


IntentHandler.swift

import WidgetKit
import SwiftUI
import CoreData
import Intents

class IntentHandler: INExtension, ConfigurationIntentHandling {
    
    var moc = PersistenceController.shared.managedObjectContext

    var timerEntity_0:TimerEntity?
    var timerEntity_1:TimerEntity?
    var timerEntity_2:TimerEntity?

    func provideNameOptionsCollection(for intent: ConfigurationIntent, searchTerm: String?, with completion: @escaping (INObjectCollection<NSString>?, Error?) -> Void) {
        
        let request = NSFetchRequest<TimerEntity>(entityName: "TimerEntity")

        do{
            let result = try moc.fetch(request)
            timerEntity_0 = result[0]
            timerEntity_1 = result[1]
            timerEntity_2 = result[2]
        }
        catch let error as NSError{
            print("Could not fetch.\(error.userInfo)")
        }

        let nameIdentifiers:[NSString] = [
            NSString(string: timerEntity_0?.task ?? "default"),
            NSString(string: timerEntity_1?.task ?? "default"),
            NSString(string: timerEntity_2?.task ?? "default")
            // "meeting",
            // "cooking",
            // "shoping"
        ]
        let allNameIdentifiers = INObjectCollection(items: nameIdentifiers)
        
        completion(allNameIdentifiers,nil)
    }
    
    override func handler(for intent: INIntent) -> Any {
        
        return self
    }
}
like image 124
Tio Avatar answered Oct 17 '25 14:10

Tio



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!