Swift NSSearchField NSArrayController No Bindings

Swift NSSearchField NSArrayController No Bindings

Created By:Debasis Das (May 2016)

In this post we will create a simple cocoa application to filter the data in a NSTableView using a NSSearchField without using Bindings

The NSArrayController will maintain the backup data in the form of its content and the NSArrayController->arrangedObjects will return the filtered contents.

//  AppDelegate.swift
//  NSSearchField_ArrayController_NoBindings
//  Created by Debasis Das on 26/05/16.
//  Copyright © 2016 Knowstack. All rights reserved.

import Cocoa

//App Delegate will be the delegate and datasource for the table view
class AppDelegate: NSObject, NSApplicationDelegate,NSTableViewDelegate,NSTableViewDataSource,NSSearchFieldDelegate {

    @IBOutlet weak var window: NSWindow!
    @IBOutlet weak var tableView:NSTableView!
    @IBOutlet weak var searchField:NSSearchField!
    var contacts:[Person] = [] //Create an empty Array to hold the person records
    var personArrayController:NSArrayController = NSArrayController()
    func applicationDidFinishLaunching(aNotification: NSNotification) {
        self.searchField.delegate = self
        for item in self.dataArray(){
            self.contacts.append(item as! Person) //Adding person objects to the contacts property

        self.personArrayController.content = contacts //Setting the contents of the array controller as the recently created contacts. 
//Alternatively the array controllers content must be updated from the data fetched from db


    override func controlTextDidChange(obj: NSNotification) {
        var searchString = ""
        searchString = ((obj.object as? NSSearchField)?.stringValue)!
        let predicate = NSPredicate(format: "firstName contains %@ OR lastName contains %@ ",searchString,searchString)
        if searchString != ""{
            self.personArrayController.filterPredicate = predicate
            self.personArrayController.filterPredicate = nil

//Table View Delegate and datasource methods
    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return self.personArrayController.arrangedObjects.count

    func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
        if let tColIdentifier = tableColumn?.identifier{
            let str = self.personArrayController.arrangedObjects[row].valueForKey(tColIdentifier)
            return str
            return ""

    func applicationWillTerminate(aNotification: NSNotification) {
        // Insert code here to tear down your application

    func dataArray()->NSMutableArray{
        let arr = NSMutableArray()
        arr.addObject(Person.createPerson("Debasis", lName: "aabb"))
        arr.addObject(Person.createPerson("John", lName: "ccdd"))
        arr.addObject(Person.createPerson("Jane", lName: "eeff"))
        return arr


class Person:NSObject{
    var firstName:String = ""
    var lastName:String = ""
    class func createPerson(fName:String, lName:String)->Person{
        let person = Person()
        person.firstName = fName
        person.lastName = lName
        return person

On build and Run
NSSearchField NSTableView NSArrayController No Bindings 1


On entering a search query

NSSearchField NSTableView NSArrayController No Bindings 2

Note: The Searches are case sensitive

The working code can be downloaded here NSSearchField_ArrayController_NoBindings

Posted in Cocoa, Swift Tagged with: , ,

Leave a Reply

Your email address will not be published. Required fields are marked *