DidSelect after SearchController is used causes crash swift - ios

I have a TableView and a Search Controller. They both work perfectly with regards to displaying the info, searching, etc. The problem arises when you go to select one of the cells.
In my code, there are 4 ways you can select the cell... If a bool isAboutNewPost == true / false, and if the search is active or not. If the search controller is active, I am using the data from a filtered array.
When you select a cell and the search controller is not active, it works perfectly. When you select a cell and the search controller is active, but the bool is false, it works perfectly. When you select a cell and the search controller is active and the bool is true, it crashes. I have no clue why, because it is almost identical code.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//
self.resultSearchController.endEditing(true)
switch(segmentControl.selectedSegmentIndex)
{
case 0:
if self.theResultSearchController.active {
self.theResultSearchController.hidesNavigationBarDuringPresentation = false
print("it is in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
theResultSearchController.active = false
print("Going to Did Select Name!")
// self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.name.text)
let sb = UIStoryboard(name: "Main", bundle: nil)
if self.isAboutNewPost == true {
print("There was a new post.")
let messagesVC = sb.instantiateViewControllerWithIdentifier("AddChinUpScreen") as! AddChinUpViewController
messagesVC.userObjectId = currentCell.nameLabel.text
messagesVC.thereWasJustANewPost = true
print("i got to right here.")
self.navigationController?.pushViewController(messagesVC, animated: true)
// new line
//self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.nameLabel.text)
} else {
print("There wasn't a new post.")
let messagesVC = sb.instantiateViewControllerWithIdentifier("AddChinUpScreen") as! AddChinUpViewController
messagesVC.userObjectId = currentCell.nameLabel.text
self.navigationController?.pushViewController(messagesVC, animated: true)
//self.performSegueWithIdentifier("didSelectName", sender: currentCell.nameLabel.text)
}
} else {
if self.isAboutNewPost == true {
print("it is not in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
print("Going to transferToAddChinUp!")
self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.nameLabel.text)
} else {
print("it is not in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
print("Going to Did Select Name!")
self.performSegueWithIdentifier("didSelectName", sender: currentCell.nameLabel.text)
}
}
break
case 1:
if self.theResultSearchController.active {
self.theResultSearchController.hidesNavigationBarDuringPresentation = false
print("it is in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
theResultSearchController.active = false
print("Going to Did Select Name!")
// self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.name.text)
let sb = UIStoryboard(name: "Main", bundle: nil)
if isAboutNewPost == true {
print("There was a new post!!!!!!")
let messagesVC = sb.instantiateViewControllerWithIdentifier("AddChinUpScreen") as! AddChinUpViewController
messagesVC.userObjectId = currentCell.nameLabel.text
messagesVC.thereWasJustANewPost = true
self.navigationController?.pushViewController(messagesVC, animated: true)
// self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.nameLabel.text)
} else {
let messagesVC = sb.instantiateViewControllerWithIdentifier("AddChinUpScreen") as! AddChinUpViewController
messagesVC.userObjectId = currentCell.nameLabel.text
self.navigationController?.pushViewController(messagesVC, animated: true)
// self.performSegueWithIdentifier("didSelectName", sender: currentCell.nameLabel.text)
}
} else {
if isAboutNewPost == true {
print("it is not in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
print("Going to transferToAddChinUp!")
self.performSegueWithIdentifier("transferToAddChinUp", sender: currentCell.nameLabel.text)
} else {
print("it is not in search")
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRowAtIndexPath(indexPath!) as! NewAddPostTableViewCell
print("Going to Did Select Name!")
self.performSegueWithIdentifier("didSelectName", sender: currentCell.nameLabel.text)
}
}
break
default:
break
}
//AddChinUpScreen
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "didSelectName" {
let completeSignUpVC = segue.destinationViewController as! AddChinUpViewController
let selectedRowIndex = self.theTableView.indexPathForSelectedRow
let currentCell = theTableView.cellForRowAtIndexPath(selectedRowIndex!) as! NewAddPostTableViewCell
completeSignUpVC.userObjectId = currentCell.nameLabel.text
} else if segue.identifier == "transferToAddChinUp" {
let completeSignUpVC = segue.destinationViewController as! AddChinUpViewController
//let selectedRowIndex = self.theTableView.indexPathForSelectedRow
//let currentCell = theTableView.cellForRowAtIndexPath(selectedRowIndex!) as! NewAddPostTableViewCell
completeSignUpVC.userObjectId = sender as! String
completeSignUpVC.thereWasJustANewPost = true
} else if segue.identifier == "tappedOnProfilePicture" {
let completeSignUpVC = segue.destinationViewController as! AddChinUpViewController
completeSignUpVC.userObjectId = sender as! String
if self.isAboutNewPost == true {
completeSignUpVC.thereWasJustANewPost = true
} else {
//completeSignUpVC
}
}
}
Here is the Error:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIFullscreenPresentationController adaptivePresentationController]: unrecognized selector sent to instance 0x7febc34cdf60'
*** First throw call stack:
(
0 CoreFoundation 0x00000001072e3f65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x00000001069d5deb objc_exception_throw + 48
2 CoreFoundation 0x00000001072ec58d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000107239f7a ___forwarding___ + 970
4 CoreFoundation 0x0000000107239b28 _CF_forwarding_prep_0 + 120
5 UIKit 0x00000001084fb389 -[UISearchController _searchPresentationController] + 134
6 UIKit 0x00000001080d7755 -[_UISearchControllerTransplantSearchBarAnimator animateTransition:] + 215
7 UIKit 0x0000000107c81ede __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 2638
8 UIKit 0x0000000107b2e4be _runAfterCACommitDeferredBlocks + 317
9 UIKit 0x0000000107b407ee _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
10 UIKit 0x0000000107b4c4e6 _afterCACommitHandler + 90
11 CoreFoundation 0x000000010720f9d7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
12 CoreFoundation 0x000000010720f947 __CFRunLoopDoObservers + 391
13 CoreFoundation 0x000000010720559b __CFRunLoopRun + 1147
14 CoreFoundation 0x0000000107204e98 CFRunLoopRunSpecific + 488
15 GraphicsServices 0x000000010a6c0ad2 GSEventRunModal + 161
16 UIKit 0x0000000107b22676 UIApplicationMain + 171
17 Chin Up 2 0x0000000104d180fd main + 109
18 libdyld.dylib 0x0000000109a5792d start + 1
19 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

I found the solution. It had to do with how the view was loaded in the first place. Commented out code was the original code. Fixed it by making it a modal segue.
#IBAction func goToUnlockPost(sender: AnyObject) {
// let vc = self.storyboard!.instantiateViewControllerWithIdentifier("NewAddPost") as! NewAddPostViewController
// vc.isAboutNewPost = true
// vc.comingFromUnlockPost = true
// self.presentViewController(vc, animated: true, completion: nil)
self.performSegueWithIdentifier("tappedUnlockPost", sender: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "tappedUnlockPost" {
let destinationNavigationController = segue.destinationViewController as! UINavigationController
let targetController = destinationNavigationController.topViewController as! NewAddPostViewController
//targetController = segue.destinationViewController as! NewAddPostViewController
targetController.isAboutNewPost = true
targetController.comingFromUnlockPost = true
}
}

Related

How and why does signal SIGABRT occur when running this code?

When I run my app, a function gets called in a view controller and when that happens I get signal SIGABRT.
How to solve this?
Function :
func setRootViewController()
{
if Auth.auth().currentUser != nil
{
let tabVC = storyboard?.instantiateViewController(withIdentifier: "TabVC") as! TestViewController
view.window?.rootViewController = tabVC
view.window?.makeKeyAndVisible()
}
else
{
let welcomeVC = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.welcomeVC) as! ViewController
view.window?.rootViewController = welcomeVC
view.window?.makeKeyAndVisible()
}
}
When it crashes I get this in the console area :
21 CoreFoundation 0x00007fff23ac4241
CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17 22 CoreFoundation 0x00007fff23ac416c
__CFRunLoopDoSource0 + 76 23 CoreFoundation 0x00007fff23ac3944 __CFRunLoopDoSources0 + 180 24 CoreFoundation
0x00007fff23abe64f __CFRunLoopRun + 1263 25 CoreFoundation
0x00007fff23abde36 CFRunLoopRunSpecific + 438 26 GraphicsServices
0x00007fff37f64bb0 GSEventRunModal + 65 27 UIKitCore
0x00007fff46d562a3 UIApplicationMain + 1621 28 Do It !
0x000000010f1b654b main + 75 29 libdyld.dylib
0x00007fff51175cf5 start + 1 ) libc++abi.dylib: terminating with
uncaught exception of type NSException (lldb)
Try to avoid force unwraps. Try this:
func setRootViewController() {
if Auth.auth().currentUser != nil {
if let tabVC = storyboard?.instantiateViewController(withIdentifier: "TabVC") as? TestViewController {
view.window?.rootViewController = tabVC
view.window?.makeKeyAndVisible()
} else {
print("TabVC doesn't exist or is not a TestViewController")
}
} else {
let welcomeVC = storyboard?.instantiateViewController(withIdentifier: Constants.Storyboard.welcomeVC)
// you don't need to cast welcomeVC to a ViewController.
view.window?.rootViewController = welcomeVC
view.window?.makeKeyAndVisible()
}
}
Let me know if this helps or if you have any follow up questions.

Crashed: com.apple.main-thread EXC_BREAKPOINT 0x0000000100c5009c keyboard_arrow_up

I am new iOS development, I got this error from firebase crash analytics. Can anyone help me why this errors occurs?
Crashed: com.apple.main-thread
0 People Time Tracking 0x100c5009c closure #1 in closure #1 in SelectJobScreen.getPreviousStatus() (SelectJobScreen.swift:798)
1 People Time Tracking 0x100cb2648 thunk for #escaping #callee_guaranteed () -> () (<compiler-generated>)
2 libdispatch.dylib 0x1e6993a38 _dispatch_call_block_and_release + 24
3 libdispatch.dylib 0x1e69947d4 _dispatch_client_callout + 16
4 libdispatch.dylib 0x1e6942004 _dispatch_main_queue_callback_4CF$VARIANT$mp + 1068
5 CoreFoundation 0x1e6ee4ec0 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
6 CoreFoundation 0x1e6edfdf8 __CFRunLoopRun + 1924
7 CoreFoundation 0x1e6edf354 CFRunLoopRunSpecific + 436
8 GraphicsServices 0x1e90df79c GSEventRunModal + 104
9 UIKitCore 0x212cc5b68 UIApplicationMain + 212
10 People Time Tracking 0x100c1afcc main (TodoItem.swift:17)
11 libdyld.dylib 0x1e69a58e0 start + 4
I've tried figuring out what could cause this crash for a few days now, and haven't been able to reproduce it. I don't see any implicit unwraps or optionals here, but sessionId is a non-optional value in the session object if that matters.
I am using swift 4.1, and the crashes occur on on iOS devices running all the different flavours of iOS 10, 11, and 12. The app does support some builds of iOS 9, but none have been reported (although that may be irrelevant because the iOS 9 user base for the app is extremely small)
In Error log it's showing this function getPreviousStatus()
func getPreviousStatus() {
let connect = JsonManger()
let app = UIApplication.shared.delegate as! AppDelegate
let user:User = app.dataManager.gUser
if Reachability.isConnectedToNetwork() {
self.showHUD( msg: "Loading...." )
connect.getLogDetails(baseUrl: user.ClientWeb, email: user.EmailID, password: user.Password, brugerId: user.BrugerID, success: { (res) in
var indud = false
if ( res.object(forKey: "indud") != nil ){
indud = res.object(forKey: "indud") as! Bool
}
if indud {
var isTodo = false
if res.object(forKey: "isToDo") != nil {
isTodo = res.object(forKey: "isToDo") as! Bool
}
if isTodo {
var str = res.object(forKey: "JobId") as! String
let index = str.index(str.startIndex, offsetBy: 1)
str = str.substring(from: index)
let prjId = Int(str)!
let project = app.dataManager.gProject.getProject(id: prjId)
let todoId = res.object(forKey: "TodoId") as! String
let todo = app.dataManager.gTodo.getTodo(id: Int(todoId)!)
self.project = project
self.todoItem = todo
app.dataManager.isCheckedin = true
self.des = res.object(forKey: "JobDescription") as? String
let startTime = res.object(forKey: "Dato2") as! String
DispatchQueue.main.async {
let ud = UserDefaults.standard
ud.set(true, forKey: "isCheckedIn")
ud.set( 1, forKey:"type")
ud.set( self.project.ID!, forKey: "projectId" )
ud.set( self.todoItem.ID! , forKey: "todoId" )
// print(" todo data is : \(self.todoItem.ID!)")
ud.set( self.des, forKey: "des")
ud.set( startTime,forKey: "startTime")
ud.set( startTime, forKey: "checkInTime" )
ud.synchronize()
self.hideHUD()
self.performSegue(withIdentifier: "goStartTodoFromSelect", sender: nil )
}
} else {
var jobId = res.object(forKey: "JobId") as! String
jobId = jobId.replacingOccurrences(of: "P", with: "")
self.des = res.object(forKey: "JobDescription") as? String
let jobCode = app.dataManager.gJobCode.getJobCode(id: Int(jobId)! )
self.jobCodeItem = jobCode
// let chekinTime = res.object(forKey: "Dato2") as! String
let startTime = "2019-05-15T19:45:00"
DispatchQueue.main.async {
app.dataManager.isCheckedin = true
let ud = UserDefaults.standard
ud.set(true, forKey: "isCheckedIn")
ud.set( 0, forKey:"type")
ud.set( jobId, forKey: "jobId" )
ud.set( startTime,forKey: "startTime")
ud.set( startTime, forKey: "checkInTime" )
if res.object(forKey: "JobDescription") != nil {
self.des = res.object(forKey: "JobDescription") as? String
ud.set( self.des, forKey: "des")
}
ud.synchronize()
DispatchQueue.main.async {
self.hideHUD()
self.performSegue(withIdentifier: "goStartJob", sender: nil )
}
}
}
} else {
DispatchQueue.main.async {
self.hideHUD()
// self.popToRoot()
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: SelectJobScreen.self) {
self.navigationController!.popToViewController(controller, animated: true)
break
}
}
}
}
}) { (error) in
DispatchQueue.main.async {
self.hideHUD()
// self.popToRoot()
for controller in self.navigationController!.viewControllers as Array {
if controller.isKind(of: SelectJobScreen.self) {
self.navigationController!.popToViewController(controller, animated: true)
break
}
}
}
}
} else {
print("Record Not Found")
}
}
Inside of that getPreviousStatus() functions getting null values , check it once using debugging
DispatchQueue.main.async {
# mainly in this thread getting error check it once
let ud = UserDefaults.standard
ud.set(true, forKey: "isCheckedIn")
ud.set( 1, forKey:"type")
ud.set( self.project.ID!, forKey: "projectId" )
ud.set( self.todoItem.ID! , forKey: "todoId" )
// print(" todo data is : \(self.todoItem.ID!)")
ud.set( self.des, forKey: "des")
ud.set( startTime,forKey: "startTime")
ud.set( startTime, forKey: "checkInTime" )
ud.synchronize()
self.hideHUD()
self.performSegue(withIdentifier: "goStartTodoFromSelect", sender: nil )
}

How to update a specific cell label using MZDownloadManager even if user move to any ViewController and came back

I'm using MZDownloadManger library to download the files using url, every thing is working fine except the label update, when i start the downloading it changes to "Starting Downloading" then starts its progress like 10% 20% etc. its working fine but when i move to any other view controller its progress stops and not update the label value to "Downloaded". i have set a flag in my local data base '0' and '1', 0 means not downloaded and 1 means downloaded.
here is the code when a user select the cell and hit for download:
func keepOfflineFiles(sender: UIButton) {
if files[sender.tag].onLocal == "1"{
self.displayAlert(title: AlertTitle.alert, message: AlertMsg.alreadyDownloaded)
} else{
if self.files[sender.tag].status == "on amazon"{
let indexPath = IndexPath.init(row: sender.tag, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as! filesTableViewCell
downloadCell.lblDetailsPro.text = "Starting Download. . ."
}
let pathString:String = ""
let fileName:String = self.files[sender.tag].file_id! + self.files[sender.tag].Extension!
if(fileName != ""){
let local_url = NSURL(fileURLWithPath: pathString.getDocumentsPath())
let filePath = local_url.appendingPathComponent(fileName)?.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath!) {
// FILE AVAILABLE
let indexPath = IndexPath.init(row: sender.tag, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as! filesTableViewCell
downloadCell.lblDetailsPro.text = "Downloaded"
}
self.fileid = self.files[sender.tag].file_id!
self.updateFileStatusToRealm()
//self.displayAlert(title: AlertTitle.alert, message: AlertMsg.alreadyDownloaded)
} else {
// FILE NOT AVAILABLE
let completeUrl:String = Tray.downloadURLBasePath + self.files[sender.tag].fileLink!
if(self.verifyUrl(urlString: completeUrl)) {
self.fileid = self.files[sender.tag].file_id!
let index:String = String(sender.tag)
self.AppDelegateObj.downloadManager.addDownloadTask(fileName as String, fileURL: completeUrl as String, destinationPath: index as String)
}
}
}
}else{
self.displayAlert(title: AlertTitle.alert, message: AlertMsg.inArchiveProcess)
}
}
}
here are the delegates of MZDownloadManager that i called in AppDelegate
To update the progress
func downloadRequestDidUpdateProgress(_ downloadModel: MZDownloadModel, index: Int) {
let root : UINavigationController = self.window?.rootViewController as! UINavigationController
if let master = root.topViewController as? TabBarController {
if let nav = master.viewControllers?[0] as? FilesVC {
nav.refreshCellForIndex(downloadModel, index: Int(downloadModel.destinationPath)!)
}
} else {
print("Somthing went wrong while downloading this file.")
}
}
When downloading finished
func downloadRequestFinished(_ downloadModel: MZDownloadModel, index: Int) {
let root : UINavigationController = self.window!.rootViewController! as! UINavigationController
if let master = root.topViewController as? TabBarController {
if let nav = master.viewControllers![0] as? FilesVC{
nav.getDownloadingStatusOfCellForIndex(downloadModel, index: Int(downloadModel.destinationPath)!)
}
} else {
print("Somthing went wrong while finishing downloading of this file.")
}
}
Method to refresh the cell label
func refreshCellForIndex(_ downloadModel: MZDownloadModel, index: Int) {
let indexPath = IndexPath.init(row: index, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as? filesTableViewCell
downloadCell?.updateCellForRowAtIndexPath(indexPath, downloadModel: downloadModel)
}
}
Method to get the cell and change value
func getDownloadingStatusOfCellForIndex(_ downloadModel: MZDownloadModel, index: Int) {
let indexPath = IndexPath.init(row: index, section: 0)
let cell = self.tblFilesPro.cellForRow(at: indexPath)
if let cell = cell {
let downloadCell = cell as? filesTableViewCell
downloadCell?.lblDetailsPro.text = "Downloaded"
self.fileid = self.files[index].file_id!
self.updateFileStatusToRealm()
}
}
here is the method which change the flag value 0 to 1 in database:
func updateFileStatusToRealm(){
let fileToUpdate = uiRealm.objects(filesDataTable.self).filter("file_id = %#", self.fileid)
let realm = try! Realm()
if let file = fileToUpdate.first {
try! realm.write {
file.onLocal = "1"
tblFilesPro.reloadData()
}
}
}

When using prepareForSegue in Swift, it wont load data correctly the first time the cell is clicked

Using the functions below it will not load the picture or the text that is retrieved from the getMore function the first time the cell is clicked. If I click on the cell it will not load until I click the back button and the re-click on the cell.The get more function sets the emailAdress, birthday, address and the url for the picture.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var indexpath : NSIndexPath = self.tableView.indexPathForSelectedRow!
var destViewController = segue.destinationViewController as! SecondView
let row: Int = indexpath.row
getMore(row)
destViewController.nameString = namesArray[row]
destViewController.companyString = companyArray[row]
destViewController.homeNumber = homeNumber[row]
destViewController.workNumber = workNumber[row]
destViewController.mobileNumber = mobileNumber[row]
destViewController.emailAddress = self.email
if let url = NSURL(string: self.largeImageURL) {
if let data = NSData(contentsOfURL: url) {
let image1 = UIImage(data: data)
destViewController.pic = image1!
}
}
destViewController.birthday = birthDate[row]
destViewController.address = self.street + self.city + self.state + self.country + self.zip
}
I guess your function getMore loads data asynchronously, so the data may not be available when you set variables.
Sure you can pass a closure in getMore function where you will set all necessary variables and use this closure when data is fully loaded, but in this case you will block the UI. I would suggest to move function getData into SecondView and call it in viewDidLoad.
You need to take your image url loading off the main thread.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var indexpath : NSIndexPath = self.tableView.indexPathForSelectedRow!
var destViewController = segue.destinationViewController as! SecondView
let row: Int = indexpath.row
getMore(row)
destViewController.nameString = namesArray[row]
destViewController.companyString = companyArray[row]
destViewController.homeNumber = homeNumber[row]
destViewController.workNumber = workNumber[row]
destViewController.mobileNumber = mobileNumber[row]
destViewController.emailAddress = self.email
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
if let url = NSURL(string: self.largeImageURL) {
if let data = NSData(contentsOfURL: url) {
dispatch_async(dispatch_get_main_queue()) {
destViewController.pic = UIImage(data: data)
}
}
}
}
destViewController.birthday = birthDate[row]
destViewController.address = self.street + self.city + self.state + self.country + self.zip
}

error : cannot convert [anyobject] to type array<_> in coercion

i implemented UISearchController on my UITablView and its Working Fine but am trying to implement the PrepareForSegue{...} but am getting some errors on my Func: updateSearchResultsForSearchController
//declaring variables//
var searchNotes = PFObject(className: "MyClass")
var filteredNotes: NSMutableArray! = NSMutableArray()
var resultSearchController = UISearchController()
var searchActive: Bool = false
..................................
..................
override func viewDidLoad() {
super.viewDidLoad()
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()
self.definesPresentationContext = true //self takes priority over the searchController presentation
self.resultSearchController.hidesNavigationBarDuringPresentation = false
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if self.resultSearchController.active
{
return self.filteredNotes.count
}else{
return self.noteObjects.count
}}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = self.tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! MasterTableViewCell
if self.resultSearchController.active
{
cell.textLabel?.text = self.filteredNotes[indexPath.row] as? String
searchNotes = (self.noteObjects.objectAtIndex(indexPath.row) as? PFObject)!
cell.MasterTitleLabel?.text = searchNotes["Title"] as? String
cell.MasterTextLabel.text = searchNotes["Fstory"] as? String
cell.MasterTimeLabel.text = searchNotes["Time"] as? String
cell.MasterLocationLabel.text = searchNotes["Location"] as? String
return cell
} else {
let object : PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
cell.MasterTitleLabel?.text = object["Title"] as? String
cell.MasterTextLabel.text = object["Fstory"] as? String
cell.MasterTimeLabel.text = object["Time"] as? String
cell.MasterLocationLabel.text = object["Location"] as? String
return cell
}}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var object :AnyObject?
if self.resultSearchController.active{
object = filteredNotes[indexPath.row]
print(filteredNotes[indexPath.row])
self.performSegueWithIdentifier("openStory", sender: self)
} else {
object = self.noteObjects[indexPath.row]
print(noteObjects[indexPath.row])
self.performSegueWithIdentifier("openStory", sender: self)
}}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let upcoming: AddNoteTableViewController = segue.destinationViewController as! AddNoteTableViewController
if (segue.identifier == "openStory"){
let indexPath = self.tableView.indexPathForSelectedRow!
if self.resultSearchController.active
{
let object: PFObject = self.filteredNotes.objectAtIndex(indexPath.row) as! PFObject
upcoming.object = object
}
else{
let object: PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
upcoming.object = object
self.tableView.deselectRowAtIndexPath(indexPath, animated: true)
}}}
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if (editingStyle == UITableViewCellEditingStyle.Delete ){
if self.resultSearchController.active
{
}else{
let object : PFObject = self.noteObjects.objectAtIndex(indexPath.row) as! PFObject
// the below for deleting the selected cell's object from server's database
// object.deleteInBackground()
//the below for deleting the selected cell's object from localstorage
object.unpinInBackground()
self.noteObjects.removeObjectAtIndex(indexPath.row)
}
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
// self.filteredNotes.removeAll(keepCapacity: false)
self.filteredNotes.removeAllObjects()
// let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
//
// let array = (self.noteObjects as NSArray).filteredArrayUsingPredicate(searchPredicate)
//
// self.filteredNotes = array as! [String]
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
var array = (self.noteObjects as! [PFObject]).map { (obj) -> Array<PFObject> in
obj["Title"] as! Array
}
//error occurring here in both lines
array = (array as NSArray).filteredArrayUsingPredicate(searchPredicate) as Array
self.filteredNotes = array as Array
self.tableView.reloadData()
}
}
in array = (array as NSarray)... line error:
MasterTableViewController.swift:281:36: Cannot convert value of type '[AnyObject]' to type 'Array<_>' in coercion
in self.filterednotes...... line error:
MasterTableViewController.swift:282:30: Cannot convert value of type '[[PFObject]]' to type 'Array<_>' in coercion
don't know how to fix this if anybody know then please tell me
thanks
error:
<Sinhgad: 0x7fa53c02c5c0, objectId: DJ0oIHi9ir, localId: (null)> {
Fstory = "test 33";
Location = "test 3333";
Time = "test 333";
Title = "test 3";
}
2015-12-05 12:50:32.604 Notes[920:81965] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't use in/contains operator with collection <Sinhgad: 0x7fa53c02c5c0, objectId: DJ0oIHi9ir, localId: (null)> {
Fstory = "test 33";
Location = "test 3333";
Time = "test 333";
Title = "test 3";
} (not a collection)'
*** First throw call stack:
(
0 CoreFoundation 0x0000000110187e65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000111ec6deb objc_exception_throw + 48
2 Foundation 0x000000011059e6b1 -[NSCompoundPredicate evaluateWithObject:substitutionVariables:] + 0
3 Foundation 0x0000000110575719 -[NSPredicateOperator performOperationUsingObject:andObject:] + 286
4 Foundation 0x0000000110574e3c -[NSComparisonPredicate evaluateWithObject:substitutionVariables:] + 313
5 Foundation 0x0000000110574c94 _filterObjectsUsingPredicate + 398
6 Foundation 0x0000000110574a84 -[NSArray(NSPredicateSupport) filteredArrayUsingPredicate:] + 279
7 Notes 0x000000010eb087c7 _TFC5Notes25MasterTableViewController38updateSearchResultsForSearchControllerfS0_FCSo18UISearchControllerT_ + 919
8 Notes 0x000000010eb0896a _TToFC5Notes25MasterTableViewController38updateSearchResultsForSearchControllerfS0_FCSo18UISearchControllerT_ + 58
9 UIKit 0x00000001113d355d -[UISearchController _performAutomaticPresentation] + 1029
10 UIKit 0x0000000110d98185 -[UISearchBar(UISearchBarStatic) _searchFieldBeginEditing] + 220
11 UIKit 0x00000001207d69a8 -[UISearchBarAccessibility _searchFieldBeginEditing] + 45
12 UIKit 0x00000001109a88c8 -[UIApplication sendAction:to:from:forEvent:] + 92
13 UIKit 0x0000000110b17328 -[UIControl sendAction:to:forEvent:] + 67
14 UIKit 0x0000000110b175f4 -[UIControl _sendActionsForEvents:withEvent:] + 311
15 UIKit 0x00000001113884d8 -[UITextField willAttachFieldEditor:] + 800
16 UIKit 0x0000000110b214f1 -[UIFieldEditor becomeFieldEditorForView:] + 938
17 UIKit 0x000000011137c979 -[UITextField _becomeFirstResponder] + 210
18 UIKit 0x0000000110d9bdc5 -[UISearchBarTextField _becomeFirstResponder] + 96
19 UIKit 0x000000011137c737 -[UITextField __resumeBecomeFirstResponder] + 52
20 UIKit 0x0000000110d9c1ce __45-[UISearchBarTextField _becomeFirstResponder]_block_invoke + 447
21 UIKit 0x00000001109b2bd6 _runAfterCACommitDeferredBlocks + 317
22 UIKit 0x00000001109c6335 _cleanUpAfterCAFlushAndRunDeferredBlocks + 95
23 UIKit 0x00000001109d2227 _afterCACommitHandler + 90
24 CoreFoundation 0x00000001100b3367 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
25 CoreFoundation 0x00000001100b32d7 __CFRunLoopDoObservers + 391
26 CoreFoundation 0x00000001100a8f2b __CFRunLoopRun + 1147
27 CoreFoundation 0x00000001100a8828 CFRunLoopRunSpecific + 488
28 GraphicsServices 0x0000000113cf9ad2 GSEventRunModal + 161
29 UIKit 0x00000001109a6d44 UIApplicationMain + 171
30 Notes 0x000000010eafec0d main + 109
31 libdyld.dylib 0x000000011304c92d start + 1
32 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I am not sure how noteObjects is defined in your code.
I think your issue is you are casting way too much, and trying to cast to just plain "Array" is not what you want. Try something like the below.
var noteObjects = [PFObject]()
var filteredNotes = [PFObject]()
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = (noteObjects as NSArray).filteredArrayUsingPredicate(searchPredicate)
filteredNotes = array as! [PFObject]
If you really want noteObjects and filteredNotes to be of type NSMutableArray rather than Swift arrays, you can try the following.
var noteObjects = NSMutableArray()
var filteredNotes = NSMutableArray()
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %#", searchController.searchBar.text!)
let array = noteObjects.filteredArrayUsingPredicate(searchPredicate)
filteredNotes = NSMutableArray(array: array)

Resources