Bertrand Bloc'h
Bertrand Bloc'h

Reputation: 145

Delete user row in Parse Data browser

import UIKit

class ListeUtilisateursPFQueryTableViewController: PFQueryTableViewController, UISearchBarDelegate {

    var images = [NSData]()

    var userObjects: NSMutableArray = NSMutableArray()

    // Table search bar
    @IBOutlet weak var searchBar: UISearchBar!

    // Initialise the PFQueryTable tableview
    override init!(style: UITableViewStyle, className: String!) {
        super.init(style: style, className: className)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        // Configure the PFQueryTableView
        self.parseClassName = "_User"
        self.textKey = "username"
        self.pullToRefreshEnabled = true
        self.paginationEnabled = false
    }

    // Define the query that will provide the data for the table view
    override func queryForTable() -> PFQuery! {

        userObjects.removeAllObjects()

        var query = PFUser.query()

        for object in objects{
            let user: PFObject = object as PFObject
            self.userObjects.addObject(user)
        }

        let array:NSArray = self.userObjects.reverseObjectEnumerator().allObjects
        self.userObjects = NSMutableArray(array: array)

        self.tableView.reloadData()
        self.refreshControl?.endRefreshing()


        if searchBar.text != "" {
            query.whereKey("searchText", containsString: searchBar.text.lowercaseString)
        }

        query.orderByAscending("username")

        return query
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }


    func searchBarTextDidEndEditing(searchBar: UISearchBar) {

        // Dismiss the keyboard
        searchBar.resignFirstResponder()

        // Force reload of table data
        self.loadObjects()
    }

    func searchBarSearchButtonClicked(searchBar: UISearchBar) {

        // Dismiss the keyboard
        searchBar.resignFirstResponder()

        // Force reload of table data
        self.loadObjects()
    }

    func searchBarCancelButtonClicked(searchBar: UISearchBar) {

        // Clear any search criteria
        searchBar.text = ""

        // Dismiss the keyboard
        searchBar.resignFirstResponder()

        // Force reload of table data
        self.loadObjects()
    }

    override func viewDidAppear(animated: Bool) {

        // Refresh the table to ensure any data changes are displayed
        tableView.reloadData()

    }

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

        // Get the new view controller using [segue destinationViewController].
        var detailScene = segue.destinationViewController as UtilisateurTableViewCell

        // Pass the selected object to the destination view controller.
        if let indexPath = self.tableView.indexPathForSelectedRow() {
            let row = Int(indexPath.row)
            detailScene.currentObject = objects[row] as? PFObject
        }
    }

    //override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath, object: PFObject) -> PFTableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("Cell") as CustomTableViewCell!
        if cell == nil {
            cell = CustomTableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell")
        }

        // Extract values from the PFObject to display in the table cell
        cell.nomUtilisateur.text = object["username"] as String!
        cell.statusUtilisateur.text = object["status"] as String!

        if (cell.statusUtilisateur.text == "Medecin"){
            cell.statusUtilisateur.textColor = UIColor.blueColor()
        }

        if (cell.statusUtilisateur.text == "Client" || cell.statusUtilisateur.text == "Cliente"){
            cell.statusUtilisateur.textColor = UIColor.lightGrayColor()
        }

        if (cell.statusUtilisateur.text == "Secrétariat"){
            cell.statusUtilisateur.textColor = UIColor.brownColor()
        }

        var thumbnail = object["imageFile"] as PFFile
        cell.photoUtilisateur.file = thumbnail
        cell.photoUtilisateur.loadInBackground()

        return cell
    }

    override func tableView(tableView: UITableView?, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath?) {

        var selectedUser:PFObject = self.userObjects.objectAtIndex(indexPath!.row) as PFObject
        selectedUser.deleteInBackground()
        self.userObjects.removeObjectAtIndex(indexPath!.row)
        self.tableView.reloadData()

    }
}

I've a problem with removing user Row in parse. With a lot of different solution on the web I made this class but a this moment I can't delete an user row in my parse backend; when I try I get this error message :

2015-03-28 15:26:53.209 IOS-EHPAD[4446:610055] -[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.
2015-03-28 15:26:57.059 IOS-EHPAD[4446:610055] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds for empty array'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010f78ea75 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x00000001112e6bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x000000010f679893 -[__NSArrayM objectAtIndex:] + 227
    3   IOS-EHPAD                           0x000000010df21a04 _TFC9IOS_EHPAD43ListeUtilisateursPFQueryTableViewController9tableViewfS0_FTGSqCSo11UITableView_18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathGSqCSo11NSIndexPath__T_ + 324
    4   IOS-EHPAD                           0x000000010df21d8f _TToFC9IOS_EHPAD43ListeUtilisateursPFQueryTableViewController9tableViewfS0_FTGSqCSo11UITableView_18commitEditingStyleOSC27UITableViewCellEditingStyle17forRowAtIndexPathGSqCSo11NSIndexPath__T_ + 79
    5   UIKit                               0x000000011011a604 -[UITableView animateDeletionOfRowWithCell:] + 130
    6   UIKit                               0x00000001100faa75 __52-[UITableView _swipeActionButtonsForRowAtIndexPath:]_block_invoke + 72
    7   UIKit                               0x0000000110022a22 -[UIApplication sendAction:to:from:forEvent:] + 75
    8   UIKit                               0x0000000110129e50 -[UIControl _sendActionsForEvents:withEvent:] + 467
    9   UIKit                               0x000000011012921f -[UIControl touchesEnded:withEvent:] + 522
    10  UIKit                               0x0000000110068b68 -[UIWindow _sendTouchesForEvent:] + 735
    11  UIKit                               0x0000000110069493 -[UIWindow sendEvent:] + 683
    12  UIKit                               0x0000000110035fb1 -[UIApplication sendEvent:] + 246
    13  UIKit                               0x0000000110043227 _UIApplicationHandleEventFromQueueEvent + 17700
    14  UIKit                               0x000000011001e23c _UIApplicationHandleEventQueue + 2066
    15  CoreFoundation                      0x000000010f6c3c91 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
    16  CoreFoundation                      0x000000010f6b9b5d __CFRunLoopDoSources0 + 269
    17  CoreFoundation                      0x000000010f6b9194 __CFRunLoopRun + 868
    18  CoreFoundation                      0x000000010f6b8bc6 CFRunLoopRunSpecific + 470
    19  GraphicsServices                    0x0000000111e4ca58 GSEventRunModal + 161
    20  UIKit                               0x0000000110021580 UIApplicationMain + 1282
    21  IOS-EHPAD                           0x000000010df0c9de top_level_code + 78
    22  IOS-EHPAD                           0x000000010df0cada main + 42
    23  libdyld.dylib                       0x0000000112454145 start + 1
    24  ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb) 

Any idea for this problem?

Upvotes: 0

Views: 938

Answers (1)

deadbeef
deadbeef

Reputation: 5563

You should follow some of the Parse tutorials on how to use PFQueryTableViewController, you're going at it the wrong way.

First of all, you are manipulating the objects array in queryForTable(). At this point the query hasn't been run, so the array is still empty, which means that your userObjects array will also be empty. If you want to go through the results of the query you should do it in the objectsDidLoad method.

But I would advise against it, because what I think you are trying to do here is change how the objects returned from the query are ordered. You should know that if you use PFQueryTableViewController, you can't change the content or the ordering of the query results. Copying this array in an other array will not work, because this new array will not be use to populate the table view.

One among the many consequences of that is that you cannot delete items in a PFQueryTableViewController. If you want to delete items, you should implement your own controller. There may be some you can use on github, I encourage you to look around, I don't have one in mind right now.

If you want a specific understanding of your crash, here it is : Your table view displays many objects (which are stored in the objects array). When you tried to delete an object in the table view, your code tried to remove this object from the userObjects array, which, as I said above, is empty. Hence the crash, you cannot remove an object from an empty array.

Upvotes: 2

Related Questions