0

Below the code of the widget timeline and the error. Fetch request returning always empty causing out of range into randomIndex. Data and fetch request working fine into all other app views including using different predicates.


error after fetching data

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        
        var entries: [WidgetContent] = []
        
        let managedObjectContext = persistenceController.container.viewContext
        
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Task");
        
        let currentDate = Date()
        
        for hourOffset in 0 ..< 5 {
            let entryDate = Calendar.current.date(byAdding: .minute, value: hourOffset, to: currentDate)!
            
            var entry = snapshotEntry
            
            var results = [Task]()
            
            do { results = try managedObjectContext.fetch(request) as! [Task] }
            catch let error as NSError { print("Could not fetch \(error), \(error.userInfo)") }
            
            let randomIndex = Int(arc4random_uniform(UInt32(results.count)))
            
            let displayComplete = results[randomIndex].isComplete
            let displayAdded = results[randomIndex].dateAdded
            let displayName = results[randomIndex].name
            let displayCategory = results[randomIndex].secondaryCategory
                
            entry = WidgetContent(date: entryDate, isComplete: displayComplete, dateAdded: displayAdded!, name: displayName!, secondaryCategory: displayCategory!)
            
            entries.append(entry)
        }
        
        let timeline = Timeline(entries: entries, policy: .atEnd)
        completion(timeline)
    }
}
EddieF
  • 81
  • 7
  • Have you set up an AppGroup? https://stackoverflow.com/questions/63922032/share-data-between-main-app-and-widget-in-swiftui-for-ios-14 and made sure that you are saving your core data into it? Also you shouldn’t be using arc4random you should use Swift’s built in random number generation https://stackoverflow.com/a/24007169/5508175 – Andrew Dec 27 '20 at 08:05
  • Yes, appgroup created and validated for both the app and the widgets also checked entitlements. Yes, as I mentioned app is working fine, saving and loading data into many views as expected also using different predicates into it. I'm just implementing the widgets. Regarding the random and arc4random, thanks! for the feedback, I'll take a look on it. – EddieF Dec 27 '20 at 13:16

1 Answers1

0

Finally I found a solution.

Added database location:

    let container: NSPersistentCloudKitContainer
    
init(inMemory: Bool = false) {
    let storeURL = AppGroup.tasks.containerURL.appendingPathComponent("Yours.sqlite")
    let description = NSPersistentStoreDescription(url: storeURL)

    container = NSPersistentCloudKitContainer(name: "Yours")
    if inMemory {
        container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
    }
    container.persistentStoreDescriptions = [description]
    container.loadPersistentStores(completionHandler: { (storeDescription, error) in
        if let error = error as NSError? {
            fatalError("Unresolved error \(error), \(error.userInfo)")
        }
    })
}

Also updated timeline to reflect these changes:

...

let managedObjectContext = PersistenceController.shared.container.viewContext
    

...

do { results = try managedObjectContext.fetch(request) as! [Task] }

...

Now it's working great. Thanks for the comments which helped a lot.

EddieF
  • 81
  • 7