Reputation: 16715
I'm presently taking an iOS development course. As part of an assignment, I'm tasked with creating a UISearchController
in a note tracking project using Core Data in Swift.
Every example I've found is in Objective-C or is filtering a static array. Apple's "sample" code, updated in December 2014 doesn't compile in Xcode 6.3.
To add a UISearchController
, I've got 3 primary tasks to do:
1) Create a view controller to present search results. I'm using a TableViewController.
2) Create a UISearchController, and pass it my search results view controller.
What's "stumping" me is now to get a hold of the objects in the managedObjectsContext. Prior to attempting to add a UISearchController
, my app works fine. I can add, edit, and delete items. I'm using the "canned" Core Data code in Xcode 6.3 with the stack in AppDelegate.
class MasterViewController: UITableViewController, NSFetchedResultsControllerDelegate
var searchController: UISearchController? = nil
func addSearchBar() {
var resultsController = SearchResultsTableViewController()
resultsController.notes = // stumped what to call the notes. Trying to call an array from the Notes class below
resultsController.delegate = self
searchController = UISearchController(searchResultsController: resultsController)
searchController!.searchResultsUpdater = resultsController
searchController!.searchBar.frame = CGRect(
x: searchController!.searchBar.frame.origin.x,
y: searchController!.searchBar.frame.origin.y, width: searchController!.searchBar.frame.size.width, height: 44.0)
tableView.tableHeaderView = searchController!.searchBar
self.definesPresentationContext = true
}
3) The UISearchController will notify its searchResultsUpdater (a class that conforms to UISearchResultsUpdating) when the search text changes. I'm using my search results view controller implement this protocol so I can update the filtered results.
Below is my Note: NSManagedObject
class:
import Foundation
import CoreData
class Note: NSManagedObject {
@NSManaged var dateCreated: NSDate
@NSManaged var dateEdited: NSDate
@NSManaged var noteTitle: String
@NSManaged var noteBody: String
// TODO: adding this to make it easier to handle names
class func notes() -> NSArray {
let whereMyNotesAreStored = // Need syntax for where my MyManagedObjectContext is located
let dataArray = NSArray(contentsOfFile: whereMyNotesAreStored!)
var notesArray = NSMutableArray()
for dictionary in dataArray {
var note = Note()
note.noteTitle = dictionary["noteTitle"] as! String
note.noteBody = dictionary["noteBody"] as! String
note.dateCreated = dictionary["dateCreated"] as! String
note.dateEdited = dictionary["dateEdited"] as! String
notesArray.addObject(note)
}
return NSArray(array: notesArray as! [AnyObject])
}
}
Upvotes: 1
Views: 1121
Reputation: 21536
There are two approaches to setting the context:
Calling back to the App Delegate:, like this
let appDelegate : AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context = appDelegate.managedObjectContext!
or passing the context forward from the App Delegate to the Master View Controller, which then passes it on to any subsequent view controllers, etc. Each view controller will need a property defined for the context; when a new VC is instantiated, the context is set before the VC is presented/pushed, eg:
class CustomViewController : UIViewController {
var managedObjectContext : NSManagedObjectContext
...
and, when loading a new view controller,
let newVC = CustomViewController()
newVC.managedObjectContext = self.managedObjectContext
...
To access the objects, use either a NSFetchRequest
or NSFetchedResultsController
to create an array of results, which you can then pass to the resultsController. eg. for a fetch request:
let fetch = NSFetchRequest(entityName: "Notes")
var error : NSError? = nil
let fetchedResults = managedObjectContext?.executeFetchRequest(fetch, error: &error)
(Your notes() function is on the wrong track - you would not use NSArray(contentsOfFile:) to access CoreData objects. Also, you must use the designated initialiser for NSManagedObject subclasses: so not var note = Notes()
but var note = Notes(entity: NSEntityDescription, insertIntoManagedObjectContext: NSManagedObjectContext?)
Upvotes: 2