Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift UITableView: How to Load data from JSON

I am beginner in Swift and would like some help for my first application.I hope that I can explain it well. I am developing and app which is loading information from a JSON File. Does someone of you know how can I populate this information into a UI Table View Cells. I have developed 3 view controllers, in the first one I have a button, which the user has to press and the 2nd Tableview controller will be opened. I have watched tutorials how to populate it but it seems that it doesn't work. The 3rd one is the Table View Cells.let me show you:

class TableViewController: UITableViewController {
@IBOutlet weak var Bar: UIToolbar!
var TableData:Array< String > = Array < String >()
let ImageList = ["",""]
var TitleList = ["",""]
let DescriptionList = ["",""]

I have to display in the cells Image, Title and Description. here is the JSON File:

 {
 “fruits” : [
 {
 “Name” : “Fruit1”,
 “Picture”:”http://www.starpropertiesindia.com/blog/wp-   content/uploads/2016/08/kochi1.jpg”,
“Description”:””,
},

  {
 “Name” : “Fruit2”,
 “Picture”:”http://www.starpropertiesindia.com/blog/wp-content/uploads/2016/08/kochi1.jpg”,
 “Description”:””,

},

I would be very thankful if someone advice me how to continue..

Prepare for segue in new view:

@IBOutlet weak var CellDescription: UILabel!
@IBOutlet weak var CellImage: UIImageView!
@IBOutlet weak var CellTitle: UILabel!
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}
like image 543
Dakata Avatar asked Aug 22 '16 10:08

Dakata


1 Answers

First of all, don't use multiple arrays for the data source. They are quite error-prone because you are responsible to keep the number of items in sync.

  • Since Swift is an object-oriented language use a custom struct as model

    struct Fruit {
      let name : String
      let imageURL : NSURL
      let description : String
    }
    
  • Declare an empty Swift array of Fruit as data source array. Basically use always Swift native collection types (rather than NSArray and NSDictionary) because they contain the type information.

    var fruits = [Fruit]()
    
  • Create a function to parse the JSON and reload the table view. The code assumes that the JSON file is named jsonFile.json and is located in the application bundle. Further it uses the SwiftyJSON library.

    func parseFruits() {
      guard let url = NSBundle.mainBundle().URLForResource("jsonFile", withExtension: "json"), jsonData = NSData(contentsOfURL: url) else {
        print("Error finding JSON File")
        return
      }
    
      let jsonObject = JSON(data: jsonData)
    
      let fruitArray = jsonObject["fruits"].arrayValue
      for aFruit in fruitArray {
        let name = aFruit["Name"].stringValue
        let imageURL = aFruit["Picture"].stringValue
        let description = aFruit["Description"].stringValue
    
        let fruit = Fruit(name: name, imageURL: NSURL(string:imageURL)!, description:description)
        fruits.append(fruit)
      }
    
      self.tableView.reloadData()
    }
    
  • in viewWillAppear call the parse function

    override func viewWillAppear() {
      super.viewWillAppear()
      parseFruits()
    }
    
  • These are the table view data source delegate methods assuming the identifier of the cell is Cell and the style of the cell is Right Detail or Subtitle

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      return fruits.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
      let fruit = fruits[indexPath.row]
      cell.textLabel!.text = fruit.name
      cell.detailTextLabel?.text = fruit.description
      // add code to download the image from fruit.imageURL
      return cell
    }
    

Edit:

In Swift 4 everything became much shorter and more convenient. The most significant change is to drop SwiftyJSON and use Decodable

struct Fruit : Decodable {
   let name : String
   let imageURL : URL
   let description : String
}

func parseFruits() {
    let url = Bundle.main.url(forResource:"jsonFile", withExtension: "json")!
    let jsonData = try! Data(contentsOfURL: url)
    self.fruits = try! JSONDecoder().decode([Fruit].self, from: jsonData)
    self.tableView.reloadData()
}
like image 191
vadian Avatar answered Nov 10 '22 23:11

vadian