简体   繁体   中英

ReloadData not working Swift with Alamofire

I tried to reload my UITableView after adding new items. When I try with a reloadData() it's not working. Nothing is shown. If I try to reload my getallrecords function, that reload items but they are repeated. My source code is :

class FriendsViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, DZNEmptyDataSetSource, DZNEmptyDataSetDelegate {
    @IBOutlet var tabeview: UITableView!
    var textArray: NSMutableArray! = NSMutableArray()
    var subArray: NSMutableArray! = NSMutableArray()
    let defaults = NSUserDefaults.standardUserDefaults()
    var valueToPass:String!
    var reports_d:String!
    var reports:String!

@IBOutlet var menuButton: UIBarButtonItem!
@IBOutlet var friends_icon: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
     tabeview.dataSource = self
    tabeview.delegate = self
    tabeview.emptyDataSetSource = self
    tabeview.emptyDataSetDelegate = self
    tabeview.tableFooterView = UIView()

    getallrecords()
    self.tabeview.addPullToRefresh({ [weak self] in
        // refresh code
        self!.getallrecords()
        self?.tabeview.stopPullToRefresh()
        })
   // Do any additional setup after loading the view.
}



func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.textArray.count   
}

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

    let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "cell")
    cell.textLabel?.text = self.textArray.objectAtIndex(indexPath.row) as? String
    cell.detailTextLabel?.text = self.subArray.objectAtIndex(indexPath.row) as? String
    return cell   
}

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    print("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell

    valueToPass = currentCell.textLabel!.text
    reports = reports_d
    performSegueWithIdentifier("friends_details", sender: self)
}
func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
    return true
}

func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
    if (editingStyle == UITableViewCellEditingStyle.Delete) {
        // handle delete (by removing the data from your array and updating the tableview)
        let currentCell = tableView.cellForRowAtIndexPath(indexPath)! as UITableViewCell
        let friend2 = currentCell.textLabel!.text

        let defaults = NSUserDefaults.standardUserDefaults()
        let username = defaults.objectForKey("name") as! String
        Alamofire.request(.GET, "http://www.example.com/app/remove_friends.php", parameters: ["key_id": "xxxxx","user_id": username,"friend_receive_id": friend2!, "action": "delete"])
            .response { request, response, data, error in
                print(request)
                print(response)
                print(error)
                if(error == nil)
                {
                    self.tabeview.beginUpdates()
                    self.textArray.removeObjectAtIndex(indexPath.row)
                    self.subArray.removeObjectAtIndex(indexPath.row)
                    tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
                    self.tabeview.endUpdates()

                }

        }

   NSNotificationCenter.defaultCenter().postNotificationName("reloadData",object: self)

    }
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?){

    if (segue.identifier == "friends_details") {

        // initialize new view controller and cast it as your view controller
        let viewController = segue.destinationViewController as! DetailsFriendsViewController
        // your new view controller should have property that will store passed value
        viewController.passedValue = valueToPass
        viewController.reports = reports
    }

}
func getallrecords(){
        if(defaults.stringForKey("name") != nil ){
            let username = defaults.objectForKey("name") as! String
            let full = "http://www.example.com/app/danger_friend_view.php?search=true&username=" + username
            let url = NSURL(string: full)
            let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
                do {
                    let d = NSString(data: data!, encoding: NSUTF8StringEncoding)
                    var arr = d!.componentsSeparatedByString("<") // spliting the incoming string from "<" operator because before that operator is our required data and storing in array
                    let dataweneed:NSString = arr[0] as NSString // arr[0] is the data before "<" operator and arr[1] is actually no use for us
                    NSOperationQueue.mainQueue().addOperationWithBlock({ () -> Void in
                        SwiftSpinner.hide()
                        do {
                            if let data = try NSJSONSerialization.JSONObjectWithData(dataweneed.dataUsingEncoding(NSUTF8StringEncoding)!, options: [NSJSONReadingOptions.MutableContainers]) as? NSArray {
                                for dd in data{
                                    var name : String = dd["danger"]! as! String
                                    self.reports_d = name
                                    let info : String = dd["username"]! as! String
                                    name = NSLocalizedString("SEND_ALERT_BEGIN",comment:"SEND_ALERT") + name + NSLocalizedString("ALERTS",comment:"ALERTS")
                                    print("ID is : \(name)")
                                    print("Username is : \(info)") 
                                    self.textArray.addObject(info)
                                    self.subArray.addObject(name)
                                }
                                self.tabeview.reloadData()
                            }
                        } catch let error as NSError {
                            print(error.localizedDescription)
                        }

                    })
                }
            }

            task.resume()
        }
    else
        {
   //Do something
        } 
     }

@IBAction func reload_data(sender: UIButton) {
    let banner = Banner(title: NSLocalizedString("RELOAD_DATA_TITLE",comment:"I'm in danger, I'm currently at  "), subtitle: NSLocalizedString("RELOAD_DATA",comment:"I'm in danger, I'm currently at  "), image: UIImage(named: "Icon"), backgroundColor: UIColor(red:52.00/255.0, green:152.00/255.0, blue:219.00/255.0, alpha:0.89))
    banner.dismissesOnTap = true
    banner.show(duration: 10.0)
    dispatch_async(dispatch_get_main_queue()) {
        //Not working ....
        self.tabeview.reloadData()
    }
}

func titleForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
    let str = "Oups"
    let attrs = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleHeadline)]
    return NSAttributedString(string: str, attributes: attrs)
}

func descriptionForEmptyDataSet(scrollView: UIScrollView!) -> NSAttributedString! {
    let str = NSLocalizedString("NO_FRIENDS_TO_SHOW",comment:"No friends to show  ")
    let attrs = [NSFontAttributeName: UIFont.preferredFontForTextStyle(UIFontTextStyleBody)]
    return NSAttributedString(string: str, attributes: attrs)
}

func imageForEmptyDataSet(scrollView: UIScrollView!) -> UIImage! {
    return UIImage(named: "no-friends")
}

func buttonTitleForEmptyDataSet(scrollView: UIScrollView!, forState state: UIControlState) -> NSAttributedString! {
    let str = NSLocalizedString("ADD_FRIENDS",comment:"Add a friend  ")
    let attrs = [NSFontAttributeName: UIFont(name: "HelveticaNeue-Light", size: 19)!]
    return NSAttributedString(string: str, attributes: attrs)
}

func emptyDataSetDidTapButton(scrollView: UIScrollView!) {
    let alert = SCLAlertView()
    let txt = alert.addTextField("Friend's username")
    alert.addButton("Add") {
        if(txt.text=="")
        {
            let banner = Banner(title: NSLocalizedString("ERROR_NO",comment:"An error occured"), subtitle: NSLocalizedString("ERROR_NO_TEXT",comment:"I'm in danger, I'm currently at  "), image: UIImage(named: "Icon"), backgroundColor: UIColor(red:152.00/255.0, green:52.00/255.0, blue:52.00/255.0, alpha:0.89))
            banner.dismissesOnTap = true
            banner.show(duration: 10.0)
        }
        else
        {

            let defaults = NSUserDefaults.standardUserDefaults()
            let username = defaults.objectForKey("name") as! String
            let remove_friend_username = txt.text! as String

            Alamofire.request(.GET, "http://www.example.com/add_friends.php", parameters: ["key_id": "xxx","user_id": username,"friend_receive_id": remove_friend_username, "action": "add"])
                .response { request, response, data, error in
                    dispatch_async(dispatch_get_main_queue()) {
                        self.tabeview.reloadData()
                        //Not working
                    }
            }

        }
    }
    alert.showEdit("Add friend", subTitle: "You can add a friend by enter his username")
}

}

I believe you are missing a little point in here buddy :)

Question 1 Why reloading tableView wont show new data ??

Your function reload_data is doing nothing more than reloading data buddy :) When you call reload data all the tableView delegates like number of rows in section,number of sections and cellForRowAtIndexPath gets called but all these methods return the value depending on the data source you provide isn't it buddy :)

So if you change the data source and then call reload data they will show you the new data :) but in your reload_data function you are not altering the data source at all :) simply calling reload data on the unalterred data source will re render the tableView again thats all :)

What you can do :)

You already have a method that fetches the new data using almofire :) just call it and in the success block anyway you are reloading the tableView :) So everything will be fine buddy :)

@IBAction func reload_data(sender: UIButton) {
    let banner = Banner(title: NSLocalizedString("RELOAD_DATA_TITLE",comment:"I'm in danger, I'm currently at  "), subtitle: NSLocalizedString("RELOAD_DATA",comment:"I'm in danger, I'm currently at  "), image: UIImage(named: "Icon"), backgroundColor: UIColor(red:52.00/255.0, green:152.00/255.0, blue:219.00/255.0, alpha:0.89))
    banner.dismissesOnTap = true
    banner.show(duration: 10.0)
    self.getallrecords() //simply call this method this will anyhow will reload data on success :)
}

Question 2 Why my tableView shows duplicate data???

Your tableView always show the data which is there in its datasource :) SO if your tableView is showing duplicate cells that means you have duplicate entry in your data source :)

You are dealing with array, in future you might migrate to coredata :) Understand one thing, when you enter or add a entry to your data source if you dont want to show duplicates you will have to handle it explicitly.

How can I do that ???

From your code I beilieve info(username) value is unique per object. So before blindly adding response to textArray check if text array already consists that object if yes then dont add it again :)

Based on the above stated assumption and believing you are making use of swift 2.0

if let data = try NSJSONSerialization.JSONObjectWithData(dataweneed.dataUsingEncoding(NSUTF8StringEncoding)!, options: [NSJSONReadingOptions.MutableContainers]) as? NSArray {
                                    for dd in data{
                                        var name : String = dd["danger"]! as! String
                                        self.reports_d = name
                                        let info : String = dd["username"]! as! String
                                        name = NSLocalizedString("SEND_ALERT_BEGIN",comment:"SEND_ALERT") + name + NSLocalizedString("ALERTS",comment:"ALERTS")
                                        print("ID is : \(name)")
                                        print("Username is : \(info)") 

                                        if  !self.textArray.contains(info){                                                                                      

                                        self.textArray.addObject(info)
                                        self.subArray.addObject(name)
                                        } 

                                    }
                                    self.tabeview.reloadData()
                                }

Now that's a lot of code, I want a easier solution :)

Clear the array before adding the new response :) Thats all :)

if let data = try NSJSONSerialization.JSONObjectWithData(dataweneed.dataUsingEncoding(NSUTF8StringEncoding)!, options: [NSJSONReadingOptions.MutableContainers]) as? NSArray {
                                self.textArray.removeAll()
                                self.subArray.removeAll() //clear the arrays and then re populate them thats all no duplicate data anymore :P
                                for dd in data{
                                    var name : String = dd["danger"]! as! String
                                    self.reports_d = name
                                    let info : String = dd["username"]! as! String
                                    name = NSLocalizedString("SEND_ALERT_BEGIN",comment:"SEND_ALERT") + name + NSLocalizedString("ALERTS",comment:"ALERTS")
                                    print("ID is : \(name)")
                                    print("Username is : \(info)") 
                                    self.textArray.addObject(info)
                                    self.subArray.addObject(name)
                                }
                                self.tabeview.reloadData()
                            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM