Search code examples
iosswiftnsfetchedresultscontrollercomputed-properties

Changing computed property in swift


I'm having NSFetchedResultsController as lazy computed property. Based on a variable, sort descriptor is created. Here's my code:

private var sortOption: Options = .none
fileprivate lazy var inspirationsResults: NSFetchedResultsController<Inspiration> = {
    // Create Fetch Request
    let fetchRequest: NSFetchRequest<Inspiration> = Inspiration.fetchRequest()

    // Configure Fetch Request
    //let optn = self.sortOption.rawValue
    switch (self.sortOption) {
    case .sortAscending:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "inspirationName", ascending: true)]
    case .sortDescending:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "inspirationName", ascending: false)]
    case .sortByAdding:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    case .sortByUpdated:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    case .showFilter:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    default:
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    }
    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "timeStamp", ascending: false)]
    fetchRequest.fetchBatchSize = 10
    // Create Fetched Results Controller
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: CoreDataManager.shared.getContext(), sectionNameKeyPath: nil, cacheName: nil)

    // Configure Fetched Results Controller
    fetchedResultsController.delegate = self

    return fetchedResultsController
}()

When sortOption variable's value is changed, I want to recompute "inspirationsResults" variable and change the sort descriptor accordingly. How to achieve it?


Solution

  • Put the code to compute the sort descriptor into the didSet observer of the sortOption property:

    private var sortOption: Options = .none {
        didSet {
            let sortDescriptor : NSSortDescriptor
            switch sortOption {
                case .sortAscending:
                    sortDescriptor = NSSortDescriptor(key: "inspirationName", ascending: true)
                case .sortDescending:
                    sortDescriptor = NSSortDescriptor(key: "inspirationName", ascending: false)
                default:
                    sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
             }
             fetchedResultsController.fetchRequest.sortDescriptors = [sortDescriptor]
             do {
                try fetchedResultsController.performFetch()
                tableView.reloadData()
             } catch {
                print(error)
             }
        }
    }
    

    The default case covers all explicit cases which sort by timeStamp - false.
    After changing the sort descriptor you need to perform a new fetch and reload the table view.

    And in the method to initialize the results controller simply write:

    self.sortOption = .none