2

I would like to create a TableView which return just one cell. Include in this cell three labels: id, username and category. This would result to let user to see his basic detail info.

When I Run the APP, my UITableView still not showing any result (blank).

Please anyone can review my code to make it works ? I can not see where I am wrong as I don't get any error in Xcode

TableView Controller

import UIKit
import Alamofire

class MyProfile: UITableViewController {

var users = [MyProfileBasicData]()

    override func viewDidLoad() {
    super.viewDidLoad()

    }
    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(true)
        getData()
    }

    func getData() {
        let prefs:NSUserDefaults = NSUserDefaults.standardUserDefaults()
        var username = prefs.valueForKey("USERNAME") as NSString

        Alamofire.request(.GET, "http://mysite/app/data/jsonuser.php", parameters: ["username": username]).responseJSON() { (_, _, data, error) in if let jsonResult = data as? Array<Dictionary<String, String>> {
            var UserID = jsonResult [0]["Id"]
            var username1 = jsonResult [0]["username"]
            var category = jsonResult [0]["category"]

            for result in jsonResult {
                var userInfo = MyProfileBasicData()
                userInfo.Id = jsonResult [0]["Id"]
                userInfo.username = jsonResult [0]["username"]
                userInfo.category = jsonResult [0]["category"]
                self.users.append(userInfo)

            }

                dispatch_async(dispatch_get_main_queue(),

                    { self.tableView.reloadData()
                    })
                println(UserID)
                println(username1)
                println(category)
            }
            println(error)
        }
    func didReceiveMemoryWarning() {

    }

   func numberOfSectionsInTableView(tableView: UITableView) -> Int {

        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return users.count
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:
        indexPath) as MyProfileCell

    var user = users[indexPath.row]
    cell.profileID?.text = user.Id
    cell.profileUsername?.text = user.username
    cell.profileCategory?.text = user.category

return cell
    }
  }

Table View Cell

import UIKit

class MyProfileCell: UITableViewCell {

    @IBOutlet weak var profileCategory: UILabel!
    @IBOutlet weak var profileID: UILabel!
    @IBOutlet weak var profileUsername: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()

    }
    override func setSelected(selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

    }

}

Data

import Foundation

class MyProfileBasicData: NSObject {

    var Id:String?
        var username:String?
        var category:String?


    }
7
  • I notice that cellForRowAtIndexPath is not defined inside the class. I'm sure this is a cut and paste error (because otherwise, how could you reference users?), but still, you should confirm. Commented Feb 21, 2015 at 14:01
  • Also, unrelated, but your Alamofire responseJSON block should make sure to empty/reset users before adding anything to it. The viewDidAppear can be called multiple times (e.g. if you push to another view controller and then pop back to this one, viewDidAppear is called again). Commented Feb 21, 2015 at 14:03
  • Rob, first of all thank you for your help. I am new to Swift and coding as well and I've spend two days with this issue. 1) What do you mean not defined inside the class? I unfortunately don't think I did a cut and paste error, I think this is one possible issue but I don't understand what you mean by not define inside the class. 2) Alamofire issue I will look about it and google it how to empty/reset users. 3) Sorry I don't really understand the technical terms, I am coding and learning at the same time. Therefore is it possible to show me how to change the code? Commented Feb 21, 2015 at 14:34
  • Your closing braces are not aligned properly. Actually, cellForRowAtIndexPath is fine (it's in the class), but you've implemented numberOfSectionsInTableView and numberOfRowsInSection as private methods inside getData. The closing brace for getData appears to have been accidentally been placed after these other three functions. Pull these functions out (or move the closing brace for the getData function). By the way, if you select all of the text (press command+a) and then reformat (press control-i), it will adjust the indentation and the problem should be self-evident. Commented Feb 21, 2015 at 15:00
  • Regarding the resetting of users, before the responseJSON block adds any new data to the array, it would reset it with self.users.removeAll(keepCapacity: true) or self.users = [MyProfileBasicData](). Commented Feb 21, 2015 at 15:04

1 Answer 1

2

The problem is that numberOfSectionsInTableView and numberOfRowsInSection are defined as methods inside getData. If you pull them out of the getData method, they should be called successfully. Note, when you pull them out, the compiler should now complain that you need to add override (like you have for cellForRowAtIndexPath).


My original response based upon standard table view issues is below.


Two possible issues are:

  1. Failure to specify the table view's delegate:

    If this was the case, your UITableViewDataDelegate methods will not get called at all. Put breakpoints/log statements in those routines and confirm they're getting called. If not, confirm that the table view's delegate and data source properties have been set properly.

  2. Failure to hook up the @IBOutlet references in the UITableViewCell subclass to the prototype cell.

    If this was the case, the custom cell properties, e.g. cell.profileID, etc., will be nil in cellForRowAtIndexPath. If they are nil, then go back to Interface Builder and hook them up.

Sign up to request clarification or add additional context in comments.

5 Comments

1) I confirm that I connect the table view's delegate and data source with "Myprofile" . How to make a log statements in those routines? 2) I also hook (Referencing Outlet) my @IBOutlet with my cell
You can just add line that says something like println(__FUNCTION__) inside the respective functions and you'll see them getting called on the Xcode console. Regarding outlet, I'd suggest also doing the println of the outlet in code, just to make sure. In cellForRowAtIndexPath, I'd also println the value getting set in the label, there, too, just to also make sure you're successfully retrieving the values successfully.
I just get value successfully when I println in my getData() func. If I put println in other func I did not get any response in Output. Is it because I wrong called the println (for example in numberOfRowsInSection I wrote println(self.users.count) or is it because it is not retrieving the values successfully?
It's probably because numberOfRowsInSection is not getting called at all (because it's currently private function inside getData), and thus cellForRowAtIndexPath will never get called either. See new point at the start of my revised answer.
Thank you Rob ! You are the King! Everything is working fine now!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.