Upgrading search example to Xcode 11 and Swift 5

I found the following code of a search example, but it was for Xcode 8 which I don't have compatible macOS to upgrade. So, I was trying to upgrade manually, I got most of it changed but still have one error to get by to be able to test. Below is the current form of AppDelegate.swift

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

import Cocoa

class AppDelegate: NSObject, NSApplicationDelegate, NSTableViewDelegate , NSTableViewDataSource {

@IBOutlet weak var window: NSWindow!
@IBOutlet weak var tableView: NSTableView!
@IBOutlet weak var searchField: NSSearchField!

var contacts:[Person] = []
var backUpContacts:[Person] = []

func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
tableView.delegate = self
tableView.dataSource = self

for item in self.dataArray(){
self.contacts.append(item as! Person)
self.backUpContacts = self.contacts //Creating a backup of the contacts, else we can also us the


func createMenuForSearchField(){
let menu = NSMenu()
menu.title = “Menu”

let allMenuItem = NSMenuItem()
allMenuItem.title = “All”
allMenuItem.target = self
allMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(sender:))

let fNameMenuItem = NSMenuItem()
fNameMenuItem.title = “First Name”
fNameMenuItem.target = self
fNameMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(sender:))

let lNameMenuItem = NSMenuItem()
lNameMenuItem.title = “Last Name”
lNameMenuItem.target = self
lNameMenuItem.action = #selector(AppDelegate.changeSearchFieldItem(sender:))


self.searchField.searchMenuTemplate = menu
self.changeSearchFieldItem(sender: allMenuItem)


@objc func changeSearchFieldItem(sender:AnyObject){
(self.searchField.cell as? NSSearchFieldCell)?.placeholderString = sender.title


func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return self.contacts.count

private func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
let identifier = tableColumn?.identifier
let str = self.contacts[row].value(forKey: identifier!.rawValue)
return str as AnyObject?

private func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {
self.contacts[row].setValue(object, forKey: (tableColumn?.identifier)!.rawValue)

func dataArray()->NSMutableArray{
let arr = NSMutableArray()
arr.add(Person.createPerson(fName: “Debasis”, lName: “Das”))
arr.add(Person.createPerson(fName: “John”, lName: “Doe”))
arr.add(Person.createPerson(fName: “Jane”, lName: “Doe”))
return arr

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

override func textDidChange(obj: NSNotification) {
if obj.object as AnyObject? === self.searchField {

let searchString = self.searchField.stringValue
var predicate:NSPredicate = NSPredicate()
if searchString.isEmpty{
self.contacts = self.backUpContacts
if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == “All”{
predicate = NSPredicate(format: “firstName contains %@ OR lastName contains %@ “,searchString,searchString)
else if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == “First Name”{
predicate = NSPredicate(format: “firstName contains %@”,searchString)
else if (self.searchField.cell as? NSSearchFieldCell)?.placeholderString == “Last Name”{
predicate = NSPredicate(format: “lastName contains %@”,searchString)
self.contacts = (self.backUpContacts as NSArray).filtered(using: predicate) as! [Person]


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


At this point I only have one error on this line:
override func textDidChange(obj: NSNotification) that I changed from original:
override func controlTextDidChange(obj: NSNotification)
and I get the message method does not override any method in its super class .. I see that controlTextDidChange is a method of a text field object. So, that is why I changed it to textDidChange.

How do I get this example going?

The method was moved from NSObject to a protocol. I think you need to add NSTextViewDelegate and remove override.

Thanks that did the trick.

Terms of Service

Privacy Policy

Cookie Policy