Swift UITableView: Load data from JSON

In this tutorial I'll explain you how to fill an iOS UITableView component by loading the data directly from an URL using the JSON format. You'll see how to define a tableview controller in swift, how to load the data from URL and how to extract the data from the JSON format.

Define the project 

Let's create a new Swift iOS single view project.

 

In the Main.storyboard you can disable the use size classes option.

 

Now you can remove the View controller that is inside the storyboard as default, we don't need that!

  

Define the layout and the custom classes

In the Main.storyboard you've to add the UITableViewController element.

 

Now you've to set a custom class for the UITableViewController that allows you to manage the data that will be displayed.

Create a new iOS Cocoa Touch Class and set the subclass as UITableViewController and the name of the class as TableController and create it.

 

 Now in the Main.storyboard select again your UITableViewController and in the identity inspector set the TableController class that you've prevously created. 

 

In the Attribute inspector turn on the is initial view controller option.

 

Now you have to select the table view cell and under the attribute inspector set the identifier to cell.  

 

TableController custom class

Now you've to implement the table controller class. This class is the core of the table. Here you'll define the download function, the json extractor function and finally the cell definition.

 The first thing you've to do is to define the array that will be used to store and read the data. Let's define the TableData String array as:


var TableData:Array< String > = Array < String >()

The viewDidLoad() is the function that will be called as soon as the view has been loaded. Inside it you should call the get_data_from_url function. We will define this function later, but let's add the function call placeholder.


var TableData:Array< String > = Array < String >()
override func viewDidLoad() {
super.viewDidLoad()
get_data_from_url("http://www.kaleidosblog.com/tutorial/tutorial.json")
}

At this link I've prepared for you a json object. This is a simple list of countries and countries' codes. If you want use this easy tool to explore this structure in a readable format.

Set the number of sections to 1 and the number of rows to the array's size.


override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return TableData.count
}

Configure now the cell to load the array string at the position defined by the indexPath object. The "cell" identifier is the same identifier name that you previously set for the cell element. The cellForRowAtIndexPath function is called for every cell that is visible on the screen at a particular moment. So, for example, if you have to load 200 cells on your table, this function is called only 10-15 times, that's because only the elements that have to be displayed are loaded. Every time you scroll your table, this function is called again for the items that have to be displayed.
In this case we'll use the textlabel that is defined in the default cell layout.


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! UITableViewCell
cell.textLabel?.text = TableData[indexPath.row]
return cell
}

let's define now the get_data_from_url function by exploiting the iOS asynchronous call.

func get_data_from_url(url:String)
{
let httpMethod = "GET"
let timeout = 15
let url = NSURL(string: url)
let urlRequest = NSMutableURLRequest(URL: url!,
cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
timeoutInterval: 15.0)
let queue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(
urlRequest,
queue: queue,
completionHandler: {(response: NSURLResponse!,
data: NSData!,
error: NSError!) in
if data.length > 0 && error == nil{
self.extract_json(data!)
}else if data.length == 0 && error == nil{
println("Nothing was downloaded")
} else if error != nil{
println("Error happened = \(error)")
}
}
)
}

When the get_data_from_url function has done the download of the json data, the extract_json function is called. Let's now implement it. This function will extract the json data and fill the TableData array. In a JSON format there are two different main types: the array and the objects. Arrays are identified by the [ ] brackets while the object are identified by the { } brackets. This two types in Swift are defined by NSArray and NSDictionary respectively. For every JSON object you've to define a safe variable (using let and the question mark) with the right type. The json used in this example has this structure:

array
   Object
       name (String)
       code (String)
   ...
   Object
       name (String)
       code (String)

 Let's now implement the extract_json function.

func extract_json(jsonData:NSData)
{
var parseError: NSError?
let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &parseError)
if (parseError == nil)
{
if let countries_list = json as? NSArray
{
for (var i = 0; i < countries_list.count ; i++ )
{
if let country_obj = countries_list[i] as? NSDictionary
{
if let country_name = country_obj["country"] as? String
{
if let country_code = country_obj["code"] as? String
{
TableData.append(country_name + " [" + country_code + "]")
}
}
}
}
}
}
do_table_refresh();
}

 

Finally we have the data into our TableData array, we only have to refresh the table in the main thread.

func do_table_refresh()
{
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
return
})
}

 

You can download the code for this example here.
UPDATE: download the swift 3 code example from here