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
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()
}