Post

Replies

Boosts

Views

Activity

WidgetKit doesn't fetch updated data from Core Data when WidgetCenter.shared.reloadAllTimelines() gets called
The app uses Core Data + CloudKit. When the app gets launched WidgetKit file fetches correct entries from Core Data but when I add new entries to Core Data from the main app and call WidgetCenter.shared.reloadTimelines() updated entries don't get fetched and old data is displayed inside the widget. Main app and Widget target have the same App group, iCloud capability enabled for both targets. When I call WidgetCenter.shared.reloadTimelines() from the Main app Widget reloads (timer added to Widget view sets to zero) but fetch from Core Data doesn't return newly added entries. Then I restart the app and correct entries get fetched. Why doesn't it fetch correct entries when WidgetCenter.shared.reloadTimelines() gets called and only works when app is relaunched? Widget's code: import WidgetKit import SwiftUI import CoreData struct Provider: TimelineProvider { &#9;&#9;func placeholder(in context: Context) -> HabitsEntry { &#9;&#9;&#9;&#9;HabitsEntry(date: Date(), habitsCount: 0) &#9;&#9;} &#9;&#9;func getSnapshot(in context: Context, completion: @escaping (HabitsEntry) -> ()) { &#9;&#9;&#9;&#9;let entry = HabitsEntry(date: Date(), habitsCount: 0) &#9;&#9;&#9;&#9;completion(entry) &#9;&#9;} &#9;&#9;func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {&#9;&#9;&#9;&#9; &#9;&#9;&#9;&#9;let managedObjectContext = Storage.viewContext &#9;&#9;&#9;&#9;let request = NSFetchRequest<NSFetchRequestResult>(entityName: "DailyHabit") &#9;&#9;&#9;&#9;let predicate = Storage.getCurrentDatePredicate() &#9;&#9;&#9;&#9;request.predicate = predicate &#9;&#9;&#9;&#9;var habits = 0 &#9;&#9;&#9;&#9;do { habits = try managedObjectContext.count(for: request)&#9;} &#9;&#9;&#9;&#9;catch let error as NSError {print ("Could not fetch \(error), \(error.userInfo)")} &#9;&#9;&#9;&#9;let entry = [HabitsEntry(date: Date(), habitsCount: habits)] &#9;&#9;&#9;&#9;let timeline = Timeline(entries: entry, policy: .never) &#9;&#9;&#9;&#9;completion(timeline) &#9;&#9;} } struct HabitsEntry: TimelineEntry { &#9;&#9;let date: Date &#9;&#9;var habitsCount: Int } struct HabitsHomeWidgetEntryView : View { &#9;&#9;var entry: Provider.Entry &#9;&#9;var body: some View { &#9;&#9;&#9;Text(entry.date, style: .timer) &#9;&#9;&#9;Text("There are \(entry.habitsCount) daily habits") &#9;&#9;} } @main struct HabitsHomeWidget: Widget { &#9;&#9;let kind: String = "HabitsHomeWidget" &#9;&#9;var body: some WidgetConfiguration { &#9;&#9;&#9;&#9;StaticConfiguration(kind: kind, provider: Provider()) { entry in &#9;&#9;&#9;&#9;&#9;&#9;HabitsHomeWidgetEntryView(entry: entry) &#9;&#9;&#9;&#9;} &#9;&#9;&#9;&#9;.configurationDisplayName("My Widget") &#9;&#9;&#9;&#9;.description("This is an example widget.") &#9;&#9;} }&#9; Here is the code for Core Data: import UIKit import CoreData import WidgetKit class Storage { &#9; &#9;static let shared = Storage() &#9; &#9;static var persistentContainer: NSPersistentContainer { &#9;&#9;return Storage.shared.persistentContainer &#9;} &#9; &#9;static var viewContext: NSManagedObjectContext { &#9;&#9;return persistentContainer.viewContext &#9;} &#9; &#9;lazy var persistentContainer: NSPersistentContainer = { &#9;&#9;let container: NSPersistentContainer &#9;&#9; &#9;&#9;let containerURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: Constants.appGroupName)! &#9;&#9;let storeURL = containerURL.appendingPathComponent("NoRegrets.sqlite") &#9;&#9;let description = NSPersistentStoreDescription(url: storeURL) &#9;&#9;if isICloudContainerAvailable { &#9;&#9;&#9;container = NSPersistentCloudKitContainer(name: Constants.persistentContainerName) &#9;&#9;} else { &#9;&#9;&#9;container = NSPersistentContainer(name: Constants.persistentContainerName) &#9;&#9;} &#9;&#9;description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey) &#9;&#9;description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey) &#9;&#9;description.shouldMigrateStoreAutomatically = true &#9;&#9;description.shouldInferMappingModelAutomatically = true &#9;&#9;let storeDescription = description &#9;&#9; &#9;&#9;container.persistentStoreDescriptions = [storeDescription] &#9;&#9; &#9;&#9;container.loadPersistentStores(completionHandler: { (storeDescription, error) in &#9;&#9;&#9;if let error = error as NSError? { &#9;&#9;&#9;&#9;return &#9;&#9;&#9;} &#9;&#9;}) &#9;&#9; &#9;&#9;container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy &#9;&#9;container.viewContext.automaticallyMergesChangesFromParent = true &#9;&#9; &#9;&#9;do { &#9;&#9;&#9;try container.viewContext.setQueryGenerationFrom(.current) &#9;&#9;} catch { &#9;&#9;&#9;print("Failed to pin viewContext to the current generation: \(error)") &#9;&#9;} &#9;&#9;return container &#9;}() &#9; &#9;var isICloudContainerAvailable: Bool { &#9;&#9;FileManager.default.ubiquityIdentityToken != nil &#9;} &#9; &#9;// MARK: - Core Data Saving support &#9;func saveContext() { &#9;&#9;let context = persistentContainer.viewContext &#9;&#9;if context.hasChanges { &#9;&#9;&#9;do { &#9;&#9;&#9;&#9;try context.save() &#9;&#9;&#9;&#9; &#9;&#9;&#9;} catch { &#9;&#9;&#9;&#9;let nserror = error as NSError &#9;&#9;&#9;&#9;print("Saving error: \(nserror)") &#9;&#9;&#9;} &#9;&#9;} &#9;} } // MARK: - Helper methods extension Storage { &#9;func getCurrentUser() -> User? { &#9;&#9;let fetchRequest = User.createFetchRequest() &#9;&#9;fetchRequest.fetchLimit = 1 &#9;&#9;fetchRequest.sortDescriptors = [NSSortDescriptor(key: "objectID", ascending: false)] &#9;&#9; &#9;&#9;let user = try? Storage.viewContext.fetch(fetchRequest).first &#9;&#9;return user &#9;} &#9; &#9;class func getCurrentDatePredicate() -> NSPredicate { &#9;&#9;var calendar = Calendar.current &#9;&#9;calendar.timeZone = NSTimeZone.local &#9;&#9;let dateFrom = calendar.startOfDay(for: Date()) &#9;&#9;let dateTo = calendar.date(byAdding: .day, value: 1, to: dateFrom) &#9;&#9;let fromPredicate = NSPredicate(format: "date >= %@", dateFrom as NSDate) &#9;&#9;let toPredicate = NSPredicate(format: "date < %@", dateTo! as NSDate) &#9;&#9;return NSCompoundPredicate(andPredicateWithSubpredicates: [fromPredicate, toPredicate]) &#9;} }
3
1
2.6k
Nov ’20
Mac Catalyst target does not build on M1 with this error: Could not read serialized diagnostics file: error("Invalid diagnostics signature")
I have a project with a Mac Catalyst target that I can not build on my m1 mac (it works fine on my older intel mac). This is the error message: Could not read serialized diagnostics file: error("Invalid diagnostics signature") (in target 'LifeViewerMac' from project 'NoRegrets') Command CompileSwift failed with a nonzero exit code Here's the xcode screenshot:
2
1
1.6k
Jan ’22