MarcoCarnevali
MarcoCarnevali

Reputation: 668

Swift Json count and create TableView

I need to create a tableview and fill that with database information that I take with json. This is the response I get from the database with json

 {
"news": [
    {
        "id": "35",
        "type": "news",
        "title": "final test for offer",
        "city": "Mumbai",
        "description": "Test description",
        "image": "http://www.saimobileapp.com/mobileappbackend/news/IMG_0421.JPG"
    },
    {
        "id": "31",
        "type": "news",
        "title": "new test",
        "city": "Mumbai",
        "description": "yes its a test msg",
        "image": "http://www.saimobileapp.com/mobileappbackend/news/Chrysanthemum.jpg"
    },
    {
        "id": "30",
        "type": "news",
        "title": "This is a test news",
        "city": "Mumbai",
        "description": "Test description",
        "image": "http://www.saimobileapp.com/mobileappbackend/news/1.jpg"
    }
]
}

These are 3 different news with title etc., so I need to count it as I will add new, and create a table view in base of that.

This is my code now to get the database information with new EDIT:

    func LoadNews() {


    let post:NSString = ""

    NSLog("PostData: %@",post);

    let url:NSURL = NSURL(string: "http://saimobileapp.com/services/sai_news.php")!

    let postData:NSData = post.dataUsingEncoding(NSASCIIStringEncoding)!

    let postLength:NSString = String( postData.length )

    let request:NSMutableURLRequest = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.HTTPBody = postData
    request.setValue(postLength as String, forHTTPHeaderField: "Content-Length")
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("application/json", forHTTPHeaderField: "Accept")


    var reponseError: NSError?
    var response: NSURLResponse?

    var urlData: NSData? = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&reponseError)

    if ( urlData != nil ) {
        let res = response as! NSHTTPURLResponse!;

        NSLog("Response code: %ld", res.statusCode);
        if (res.statusCode >= 200 && res.statusCode < 300)
        {
            let responseData:NSString  = NSString(data:urlData!, encoding:NSUTF8StringEncoding)!

            NSLog("Response ==> %@", responseData);

            var error: NSError?

                         var Title: [String] = []

            if let jsonData = NSJSONSerialization.JSONObjectWithData(urlData!, options: nil, error: &error) as? [String:AnyObject] { // dictionary
                if let locationsArray = jsonData["news"] as? [[String:AnyObject]] { // array of dictionaries
                    for locationDictionary in locationsArray { // we loop in the array of dictionaries
                        if let location = locationDictionary["title"] as? String { // finally, access the dictionary like you were trying to do

                            Title.append(location)

                            var SaveTitle = save.setObject(Title, forKey: "NewsTitle")

                        }
                    }
                }
            }










        }




    }


}

And for TableView i use that now :

    // MARK:  UITextFieldDelegate Methods
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}


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

   var FormName = save.arrayForKey("NewsTitle")!

    return FormName.count
}







func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var FormName = save.arrayForKey("NewsTitle")!

    var cell:UITableViewCell = self.TableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell

    let row = indexPath.row

    cell.textLabel?.text = FormName[indexPath.row] as! String





    if (indexPath.row % 2 == 0) {
        cell.backgroundColor = UIColor.clearColor()
    }else{

        cell.backgroundColor = UIColor.clearColor()
        cell.textLabel?.backgroundColor = UIColor.whiteColor().colorWithAlphaComponent(0.0)
    }




    cell.textLabel?.textColor = UIColor.whiteColor()
    return cell

}
// MARK:  UITableViewDelegate Methods
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    TableView.deselectRowAtIndexPath(indexPath, animated: false)

    let row = indexPath.row

How can i show the description in the second page when i tap on the cell?

Can anyone please help me? Thanks in advance.

Upvotes: 1

Views: 1493

Answers (2)

Abhinav
Abhinav

Reputation: 38162

Follow these steps to render your table view:

Assuming you have set your view controller as datasource and delegate for UITableViewController.

  1. In your table view controller' subclass: inside loadView or viewWillAppear make server call to fetch the details. [This you might already be doing]
  2. Create a global parameter to hold to that data. e.g. self.vehicles = jsonData["news"]
  3. After server response, call reloadDatamethod on self.tableView. This will trigger calls to your table data sources methods - numberOfRowsInSection:, cellForRowAtIndexPath: etc.
  4. Return correct values from data source methods. Based on your needs you can create a custom cell and use self.vehicles to fetch & render data on it.

Edit: Example

Your data is a array of dictionary where array count will drive the number of cells in the table. That said, lets say there are 5 dictionaries in your array so you have 5 cells. When you get a call on cellForRowAtIndexPath:, use 'index path.row' to get the right dictionary mapped to the cell in request. Now, fetch the values inside that dictionary and set them on cell. Like this:

override func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath?) -> UITableViewCell? {
    // Configure the cell...
    let cellId: NSString = "Cell"
    var cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(cellId) as UITableViewCell

    if let ip = indexPath {
        var data = self.vehicles[ip.row] as NSDictionary
        cell.textLabel.text = data.valueForKey("title") as String
    }

    return cell
}

Similarly implement didSelectRowAtIndexPath and then fetch & pass on description to your target view controller for display.

Edit 2 (On OP request):

Based on second screen design (table controller or simple view controller), create a new controller class. Then, as I mentioned above, implement didSelectRowAtIndexPath something like below:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    var description = String()

    if let ip = indexPath {
        var data = self.vehicles[ip.row] as NSDictionary
        description = data.valueForKey("description") as String
    }

    var descriptionVC = SecondScreenVC(withDescription: description)
    self.navigationController.pushViewController(descriptionVC, animated: true)
}

Some references:

Apple Docs on UITableViewController

Handling UITableViewController Programmatically

Upvotes: 1

vadian
vadian

Reputation: 285072

The object of key news is an Array (of dictionaries), not a Dictionary

if let vehicles = jsonData["news"] as? NSArray {
   for vehicle in vehicles {
      let vehiclesKeys = vehicle.allKeys
         println(vehiclesKeys)
         println("123")
        }
    }
}

vehicles.count gives you the number of items in the array.

Upvotes: 1

Related Questions