Nathan Modern Nathan Modern - 5 months ago 35
Swift Question

UISearchController crash when selected

I tried to implement a UISearchController into my ViewController. However, when I try to open up the Controller from a button it crashes the application and there is no error given to me from Xcode. I am using Backendless to store users and to retrieve them. I want to search through them.
Here is my code. I don't know what I am doing wrong :/ I would really appreciate the help.

import UIKit

protocol ChooseUserDelegate {
func chreatChatroom(withUser: BackendlessUser)
}

class ChooseUserViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {

@IBOutlet weak var tableView: UITableView!


var delegate: ChooseUserDelegate!
var users: [BackendlessUser] = []
var filteredUsers = [BackendlessUser]()
var resultSearchController: UISearchController!

override func viewDidLoad() {
super.viewDidLoad()

loadUsers()
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}


//MARK: UITableviewDataSorce
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}

func updateSearchResultsForSearchController(searchController: UISearchController) {

self.filteredUsers.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!); let array = (self.users as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.filteredUsers = array as! [BackendlessUser]

self.tableView.reloadData()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if resultSearchController.active
{
return self.filteredUsers.count
} else {
return users.count
}
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {


let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell?

if self.resultSearchController.active
{
let userFiltered = filteredUsers[indexPath.row]
cell!.textLabel?.text = userFiltered.name
} else {
let user = users[indexPath.row]
cell!.textLabel?.text = user.name
}

return cell!
}


//MARK: UITableviewDelegate
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

let user = users[indexPath.row]

delegate.chreatChatroom(user)

tableView.deselectRowAtIndexPath(indexPath, animated: true)
self.dismissViewControllerAnimated(true, completion: nil)
}


//MARK: IBactions
@IBAction func cancelButtonPressed(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}

//MARK: Load Backendless Users

func loadUsers() {

let whereClause = "objectId != '\(backendless.userService.currentUser.objectId)'"

let dataQuery = BackendlessDataQuery()
dataQuery.whereClause = whereClause

let dataStore = backendless.persistenceService.of(BackendlessUser.ofClass())
dataStore.find(dataQuery, response: { (users : BackendlessCollection!) -> Void in

self.users = users.data as! [BackendlessUser]
self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self

self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()

self.tableView.tableHeaderView = self.resultSearchController.searchBar

self.tableView.reloadData()


}) { (fault : Fault!) -> Void in
print("Error, couldnt retrieve users: \(fault)")
}

}

}

Answer

Your resultSearchController is nil before it is used. It's set in a closure that almost certainly sets it after it's needed when setting up the view. To fix it, just move this initialization code to something earlier like viewDidLoad():

self.resultSearchController = UISearchController(searchResultsController: nil)
self.resultSearchController.searchResultsUpdater = self

self.resultSearchController.dimsBackgroundDuringPresentation = false
self.resultSearchController.searchBar.sizeToFit()

self.tableView.tableHeaderView = self.resultSearchController.searchBar
Comments