Search code examples
iosuitableviewswiftreloaddatacustom-cell

Swift - ReloadData does not work


So I've been looking around at the other questions where people have this problem, but I can't seem to find one where my problem is being solved.

I want to use a button to refresh and reload new data into my tableview, and with the same button I'm retrieving data:

@IBOutlet var tv: UITableView!
@IBAction func refreshTapped(sender: AnyObject) {
    var query = PFQuery(className:"textMessage")
    query.whereKey("Receiver", equalTo:PFUser.currentUser().username)
    query.findObjectsInBackgroundWithBlock {
        (objects: [AnyObject]!, error: NSError!) -> Void in
        if error == nil {
            NSLog("Successfully retrieved \(objects.count) scores.")
            var image = UIImage()


            for object in objects{

            let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
            let contxt: NSManagedObjectContext = appDel.managedObjectContext!
            let ene = NSEntityDescription.entityForName("MessageInformation", inManagedObjectContext: contxt)
            var newMessage = Messages(entity: ene!, insertIntoManagedObjectContext: contxt)

            let type = object["MessageType"] as Int

                switch type{

                case 0:
                    let message: String = object["Message"] as String
                    let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).txt"
                    message.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
                    println(path)
                    newMessage.sender = object["Receiver"] as String

                case 1:
                    let userImageFile = object["Image"] as PFFile
                    userImageFile.getDataInBackgroundWithBlock {
                        (imageData: NSData!, error: NSError!) -> Void in
                        if error == nil {
                            image = UIImage(data:imageData)
                            let imageToSave:NSData = UIImagePNGRepresentation(image)
                            let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).png"
                            imageToSave.writeToFile(path, atomically: true)
                            println(path)
                        }
                    }
                newMessage.sender = object["Receiver"] as String

                case 2:
                    let message: String = object["Message"] as String
                    let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).txt"
                    message.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
                    println(path)
                    newMessage.sender = object["Receiver"] as String


                case 3:
                    let userImageFile = object["Image"] as PFFile
                    userImageFile.getDataInBackgroundWithBlock {
                        (imageData: NSData!, error: NSError!) -> Void in
                        if error == nil {
                            image = UIImage(data:imageData)
                            let imageToSave:NSData = UIImagePNGRepresentation(image)
                            let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).png"
                            imageToSave.writeToFile(path, atomically: true)
                            println(path)
                        }
                    }
                    newMessage.sender = object["Receiver"] as String

                default:
                    println("Type not found")
                }
            }
            }else {
            // Log details of the failure
            NSLog("Error: %@ %@", error, error.userInfo!)
        }
    }
 self.tv.reloadData()
}

and this just doesn't work, I'm also pretty sure my referencing is all good. Here is my viewDidLoad-function too, if that helps:

override func viewDidLoad() {
    super.viewDidLoad()

    var nib = UINib(nibName: "TableViewCell", bundle: nil)
    tv.registerNib(nib, forCellReuseIdentifier: "cell")

    let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext!

    let fetchReq = NSFetchRequest(entityName: "MessageInformation")
    let en = NSEntityDescription.entityForName("MessageInformation", inManagedObjectContext: context)
    let sortDescriptor = NSSortDescriptor(key: "dateReceived", ascending: false)
    fetchReq.sortDescriptors = [sortDescriptor]

    messageList = context.executeFetchRequest(fetchReq, error: nil) as [Messages]

    tv.reloadData()
}

I've been programming in swift for a little while now, and still haven't gotten this functionality correct.

Any suggestions on how to proceed would be appreciated.

EDIT: My cellForRowAtIndexPath-function:

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

    let longPress: UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: "cellLongPressed:")
    longPress.delegate = self
    longPress.minimumPressDuration = 0.5
    longPress.numberOfTouchesRequired = 1

    let cell:TableViewCell = self.tv.dequeueReusableCellWithIdentifier("cell") as TableViewCell
    cell.addGestureRecognizer(longPress)

    let data = messageList[indexPath.row] as Messages
    cell.labelOutl.text = data.sender

    return cell
}

Solution

  • Your self.tv.reloadData() is outside of the closure, so while the data retrieval will occur asynchronously, you are calling reloadData immediately - before the data has been retrieved.

    It should be -

    @IBOutlet var tv: UITableView!
    @IBAction func refreshTapped(sender: AnyObject) {
        var query = PFQuery(className:"textMessage")
        query.whereKey("Receiver", equalTo:PFUser.currentUser().username)
        query.findObjectsInBackgroundWithBlock {
            (objects: [AnyObject]!, error: NSError!) -> Void in
            if error == nil {
                NSLog("Successfully retrieved \(objects.count) scores.")
                var image = UIImage()
    
    
                for object in objects{
    
                let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
                let contxt: NSManagedObjectContext = appDel.managedObjectContext!
                let ene = NSEntityDescription.entityForName("MessageInformation", inManagedObjectContext: contxt)
                var newMessage = Messages(entity: ene!, insertIntoManagedObjectContext: contxt)
    
                let type = object["MessageType"] as Int
    
                    switch type{
    
                    case 0:
                        let message: String = object["Message"] as String
                        let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).txt"
                        message.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
                        println(path)
                        newMessage.sender = object["Receiver"] as String
    
                    case 1:
                        let userImageFile = object["Image"] as PFFile
                        userImageFile.getDataInBackgroundWithBlock {
                            (imageData: NSData!, error: NSError!) -> Void in
                            if error == nil {
                                image = UIImage(data:imageData)
                                let imageToSave:NSData = UIImagePNGRepresentation(image)
                                let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).png"
                                imageToSave.writeToFile(path, atomically: true)
                                println(path)
                            }
                        }
                    newMessage.sender = object["Receiver"] as String
    
                    case 2:
                        let message: String = object["Message"] as String
                        let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).txt"
                        message.writeToFile(path, atomically: true, encoding: NSUTF8StringEncoding, error: nil)
                        println(path)
                        newMessage.sender = object["Receiver"] as String
    
    
                    case 3:
                        let userImageFile = object["Image"] as PFFile
                        userImageFile.getDataInBackgroundWithBlock {
                            (imageData: NSData!, error: NSError!) -> Void in
                            if error == nil {
                                image = UIImage(data:imageData)
                                let imageToSave:NSData = UIImagePNGRepresentation(image)
                                let path = NSTemporaryDirectory() + "\(Int(self.createRandiAndSaveNumberToCell())).png"
                                imageToSave.writeToFile(path, atomically: true)
                                println(path)
                            }
                        }
                        newMessage.sender = object["Receiver"] as String
    
                    default:
                        println("Type not found")
                    }
                }
                dispatch_async(dispatch_get_main_queue(),{ ()->() in 
                    self.tv.reloadData()
                })
                }else {
                // Log details of the failure
                NSLog("Error: %@ %@", error, error.userInfo!)
            }
        }
    }
    

    But you have another problem - you don't actually do anything with the newMessage variable to update your data model