Post

Replies

Boosts

Views

Activity

Trying to populate widget using custom intent and Core Data cause the widget to crash when rendering SwiftUI Views
Hi, I am building a to do list app that has a user configurable widget which should allow the user to select any of their lists and show the to do items in that particular list. I have created an Intent Definition and can retrieve all the list names from Core Data in the Edit Widget option on long press. But when I use that list name to retrieve the to dos and display them in the SwiftUI Entry View the widget crashes because data has not yet been populated in the Timeline entry. Intent Handler: func provideListNameOptionsCollection(for intent: SelectListIntent, with completion: @escaping (INObjectCollection<List>?, Error?) -> Void) {      let listNames: [List] = CoreDataManager.shared.fetchAllListNames().map { listName in       let name = List(identifier: listName, display: listName)       return name     }     let collection = INObjectCollection(items: listNames)     completion(collection, nil)   } Core Data Manager: func fetchAllListNames() -> [String] {     var listNames = [String]()     let context = PersistenceController.init().container.viewContext     let fetchRequest = NSFetchRequest<TaskLists>(entityName: "TaskLists")     if let lists = try? context.fetch(fetchRequest) {       for list in lists {         listNames.append(list.name)       }     }     return listNames   } func fetchItemsAgainstListName(_ name: String) -> [Item]? {     let context = PersistenceController.init().container.viewContext     let fetchRequest = NSFetchRequest<Item>(entityName: "Item")     fetchRequest.sortDescriptors = [NSSortDescriptor(keyPath: \Item.starred, ascending: false), NSSortDescriptor(keyPath: \Item.checked, ascending: true), NSSortDescriptor(keyPath: \Item.timestamp, ascending: false)]     fetchRequest.predicate = NSPredicate(format: "list.name_ = %@", name)     let items = try? context.fetch(fetchRequest)     return items   } Widget struct Provider: IntentTimelineProvider {   func placeholder(in context: Context) -> SimpleEntry {     return SimpleEntry(date: Date(), relevance: nil, items: [Item]())   }       func getSnapshot(for configuration: SelectListIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {     let entry = SimpleEntry(date: Date(), relevance: nil, items: [Item]())     completion(entry)   }       func getTimeline(for configuration: SelectListIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {     let items = list(for: configuration)     let entries = [SimpleEntry(date: Date(), relevance: nil, items: items)]           let timeline = Timeline(entries: entries, policy: .never)           completion(timeline)   }       func list(for configuration: SelectListIntent) -> [Item] {     if let name = configuration.listName?.identifier, let list = CoreDataManager.shared.fetchItemsAgainstListName(name) {       return list     }     return [Item]()   } } struct SimpleEntry: TimelineEntry {   let date: Date   let relevance: TimelineEntryRelevance?   let items: [Item] } struct checklist_widgetEntryView : View {   var entry: Provider.Entry       var body: some View {     ZStack {       VStack(alignment: .leading) {         ForEach(entry.items, id: \.self) { item in           Text("\(item.content ?? "")")         }       }     }     .onAppear {       print(entry.items)     }   } } The error is *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Item content]: unrecognized selector sent to instance 0x6000008e1950' and occurs on the Text view in my ForEach The ZStack onAppear shows that the list is entry is indeed an empty Array but if i put a print in fetchItemsAgainstListName it shows that items actually contains all the todos correctly. Any ideas on what I am doing wrong here?
2
0
809
May ’21