Kleinfeltersville
Kleinfeltersville

Reputation: 117

How to populate tableview faster with big JSON data

I have an app that retrieves json data from my server using Alamofire. I parse this json data using SwiftyJSON and then populate my table view. However I have a problem with the performance, it's very slow, it takes 6 seconds to load the table view with the received data (90 orders) and it takes longer with the number of orders increasing. I don't think the problem is with Alomofire. How do I a parse and populate my table view faster similar to twitter or facebook? This is what I have

// Order class
class Order {
  var id:Int
  var firstName:String
  var lastName:String
  var shippingAddress1:String
  var dateTime:String
  var total:String
  var status:String

  init(id:Int, firstName:String, lastName:String, shippingAddress1:String, dateTime:String, total:String, status:String){
    self.id = id
    self.firstName = firstName
    self.lastName = lastName
    self.shippingAddress1 = shippingAddress1
    self.dateTime = dateTime
    self.total = total
    self.status = status
 }
}

Below is my orders table view controller code.

 var api = API() // Making Alamofire requests
 var orders = [Order]() // Order model

 override func viewDidLoad() {
    super.viewDidLoad()
    self.makeCall() // Make api call to server
}

func makeCall(){
    // Get orders
    self.api.call(to: "orders?filter[limit]=100") { (result:NSDictionary?, error) -> () in
        if error == nil{
            self.setOrdersData(result!) // Received data
        }
    }
}

func setOrdersData(data:NSDictionary){
    let json = JSON(data) // SwiftyJSON
    let qos = Int(QOS_CLASS_USER_INITIATED.value)
    // Process it in the background
    dispatch_async(dispatch_get_global_queue(qos, 0), { () -> Void in

        // Loop through the orders and parse them
        for index in 0...json["orders"].count-1{
            let id:Int = json["orders"][index]["id"].intValue
            let firstName = json["orders"][index]["shipping_address"]["first_name"].stringValue
            let lastName = json["orders"][index]["shipping_address"]["last_name"].stringValue
            let shippingAddress1 = json["orders"][index]["shipping_address"]["address_1"].stringValue
            let dateTime = json["orders"][index]["completed_at"].stringValue
            let total = json["orders"][index]["total"].stringValue
            let status = json["orders"][index]["status"].stringValue

            // Append order to Order model
            self.orders.append(Order(id: id, firstName: firstName, lastName: lastName, shippingAddress1: shippingAddress1, dateTime: dateTime, total: total, status: status))
        }
        // Get the main thread
        dispatch_async(dispatch_get_main_queue(), { () -> Void in
            self.orders.sort({$0.id > $1.id}) // Sort orders
            self.tableView.reloadData() // Reload tableView
        })
    })
}

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:OrdersTableViewCell = tableView.dequeueReusableCellWithIdentifier("orderCell", forIndexPath: indexPath) as! OrdersTableViewCell
    let order = self.orders[indexPath.row]

    cell.labelAddress.text = order.shippingAddress1.capitalizedString
    var fullName:String = order.firstName + " " + order.lastName
    cell.labelFullName.text = fullName.capitalizedString

    cell.labelAmount.text = "$\(order.total)"


    cell.labelStatus.text = order.status
    cell.labelTime.text = "\(order.dateTime)"
    return cell
}

Upvotes: 2

Views: 894

Answers (1)

Michael Baltaks
Michael Baltaks

Reputation: 2171

The first step to solving a performance problem is to profile. Which part of the code is slow? Either use the performance profiling tools in Xcode, or split this code up into separate functions (a good idea anyway) and measure the run time of each function. When you can see which part of the code is taking the most time, you can work out a plan to change that part.

Upvotes: 1

Related Questions