Skip to content

Commit

Permalink
Cleaning up how fetched controllers are creating, a bit more performant
Browse files Browse the repository at this point in the history
  • Loading branch information
MrAdamBoyd committed Oct 29, 2017
1 parent 5768b1e commit e83d76e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 29 deletions.
64 changes: 37 additions & 27 deletions DownTube/DownTube/Helpers/CoreDataController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CoreDataController {
if let controller = _fetchedVideosController {
return controller
}
_fetchedVideosController = self.createControllerWithFetchRequest(Video.fetchRequest(), searchForPredicate: nil, isDownloadedPredicate: nil)
_fetchedVideosController = self.createControllerWithFetchRequest(Video.fetchRequest(), search: nil, isDownloaded: nil)
return _fetchedVideosController!
}
private var _fetchedVideosController: NSFetchedResultsController<Video>?
Expand All @@ -30,7 +30,7 @@ class CoreDataController {
if let controller = _fetchedStreamingVideosController {
return controller
}
_fetchedStreamingVideosController = self.createControllerWithFetchRequest(StreamingVideo.fetchRequest(), searchForPredicate: nil, isDownloadedPredicate: nil)
_fetchedStreamingVideosController = self.createControllerWithFetchRequest(StreamingVideo.fetchRequest(), search: nil, isDownloaded: nil)
return _fetchedStreamingVideosController!
}
private var _fetchedStreamingVideosController: NSFetchedResultsController<StreamingVideo>?
Expand All @@ -39,31 +39,15 @@ class CoreDataController {
///
/// - Parameter fetchRequest: request type that contains the entity
/// - Returns: fetched results controller
private func createControllerWithFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>, searchForPredicate: String?, isDownloadedPredicate: Bool?) -> NSFetchedResultsController<T> {
func createControllerWithFetchRequest<T>(_ fetchRequest: NSFetchRequest<T>, search: String?, isDownloaded: Bool?) -> NSFetchedResultsController<T> {
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20

//Sort by name
let sortDescriptor = NSSortDescriptor(key: "title", ascending: true, selector: #selector(NSString.localizedCaseInsensitiveCompare(_:)))

fetchRequest.sortDescriptors = [sortDescriptor]

var predicates: [NSPredicate] = []
if let search = searchForPredicate, search != "" {
//Searching the title
let predicate = NSPredicate(format: "title CONTAINS[cd] %@", search)
predicates.append(predicate)
}

if let isDownloadedPredicate = isDownloadedPredicate {
//Searching if item is downloaded
let predicate = NSPredicate(format: "isDoneDownloading == %@", NSNumber(value: isDownloadedPredicate))
predicates.append(predicate)
}

if !predicates.isEmpty {
fetchRequest.predicate = NSCompoundPredicate(andPredicateWithSubpredicates: predicates)
}
fetchRequest.predicate = self.predicatesWithSearch(search, isDownloaded: isDownloaded)

// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
Expand All @@ -77,21 +61,47 @@ class CoreDataController {

return aFetchedResultsController
}

/// Creates a new fetch result controller with the search provided. If no search, returns all
///
/// - Parameter search: search to use as an NSPredicate
func createVideosFetchedResultsControllerWithSearch(_ search: String?, isDownloadedPredicate: Bool?) -> NSFetchedResultsController<Video> {
return self.createControllerWithFetchRequest(Video.fetchRequest(), searchForPredicate: search, isDownloadedPredicate: isDownloadedPredicate)
func createVideosFetchedResultsControllerWithSearch(_ search: String?, isDownloaded: Bool?) -> NSFetchedResultsController<Video> {
return self.createControllerWithFetchRequest(Video.fetchRequest(), search: search, isDownloaded: isDownloaded)
}

/// Sets a new fetch result controller with the search provided. If no search, returns all
private func predicatesWithSearch(_ search: String?, isDownloaded: Bool?) -> NSCompoundPredicate {
var predicates: [NSPredicate] = []
if let search = search, search != "" {
//Searching the title
let predicate = NSPredicate(format: "title CONTAINS[cd] %@", search)
predicates.append(predicate)
}

if let isDownloadedPredicate = isDownloaded {
//Searching if item is downloaded
let predicate = NSPredicate(format: "isDoneDownloading == %@", NSNumber(value: isDownloadedPredicate))
predicates.append(predicate)
}

return NSCompoundPredicate(andPredicateWithSubpredicates: predicates) //Doesn't matter if empty
}

/// Sets the predicate for the fetched videos controller and performs the fetch
///
/// - Parameter search: search to use as an NSPredicate
func setVideosFetchedResultsControllerWithSearch(_ search: String?, isDownloadedPredicate: Bool?) {
_fetchedVideosController = self.createVideosFetchedResultsControllerWithSearch(search, isDownloadedPredicate: isDownloadedPredicate)
/// - Parameters:
/// - search: search, optional
/// - isDownloaded: if true, only looks for downloaded video
func setSearchForDownloadedVideos(_ search: String?, isDownloaded: Bool?) {
self.fetchedVideosController.fetchRequest.predicate = self.predicatesWithSearch(search, isDownloaded: isDownloaded)

do {
try self.fetchedVideosController.performFetch()
} catch let error {
print("Could not search for videos: \(error)")
}
}


//Rest of the core data stack

lazy var applicationDocumentsDirectory: URL = {
Expand Down
2 changes: 1 addition & 1 deletion DownTube/DownTube/Helpers/VideoManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ class VideoManager: NSObject, DownloadManagerDelegate {

/// Checks if any video files don't exist and need to be downloaded
func checkIfAnyVideosNeedToBeDownloaded() {
guard let needToDownload = CoreDataController.sharedController.createVideosFetchedResultsControllerWithSearch(nil, isDownloadedPredicate: false).fetchedObjects, !needToDownload.isEmpty else {
guard let needToDownload = CoreDataController.sharedController.createVideosFetchedResultsControllerWithSearch(nil, isDownloaded: false).fetchedObjects, !needToDownload.isEmpty else {
return
}
var indexesToReload: [Int] = []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ extension MasterViewController: UISearchResultsUpdating {
guard let search = searchController.searchBar.text else { return }

print("Updating search results, search is \"\(search)\"")
CoreDataController.sharedController.setVideosFetchedResultsControllerWithSearch(search, isDownloadedPredicate: nil)
CoreDataController.sharedController.setSearchForDownloadedVideos(search, isDownloaded: nil)
self.tableView.reloadData()
}
}

0 comments on commit e83d76e

Please sign in to comment.