Reputation: 3050
I'm trying to parse a large JSON file (approx: 1000 rows containg a tuple with 8 strings) and display this in a UITableView
. What I already have is working but I am looking for a more efficient way of displaying them.
At the moment my code looks likes this:
public func GET(request: String, callback: (result: JSON?, response: NSHTTPURLResponse?, error: NSError?) -> Void) {
let session = NSURLSession.sharedSession()
let url = NSURL(string : "SOMEURL")
let task = session.dataTaskWithURL(url!){
(data, response, error) -> Void in
if error != nil {
callback(result: nil, response: response as? NSHTTPURLResponse, error: error!)
} else {
callback(result: JSON(data : data!), response: response as? NSHTTPURLResponse, error: nil)
}
}
task.resume()
}
This does parse the data using SwiftJSON
(see JSON(data : data!)), then when it comes to actually filling an array i use a class containing two attributes (one for the Main text in table and one for detail text)
class SomeClass {
let MainText : String
let DetailText : String
init(MainText : String, DetailText : String) {
self.MainText = MainText
self.DetailText = Detailtext
}
}
Now in the UITableView
i have a .swift file and in the
override func ViewDidLoad() {
//code
}
I use a loop to get the data from the result callback in the GET method to append to an array of
var rows : [SomeClass] = []
This is very CPU intensive but I did not find another way to deal with this problem. I tried only displaying 50 rows in the table and only creating 50 class items for the rows. But none of that matters, what I fear is that the SwiftyJSON
way of dealing with this problem is not the right one but i thought that maybe I am overlooking something.
Upvotes: 0
Views: 808
Reputation: 307
If I understood your problem, you are worried about CPU / Energy Efficiency.
What you should consider, if it's not how your app already works, is implementing the parsing process in the background thread, make your [SomeClass] array observable and update the table when it changes (aka when the background parsing added an new value to it).
So first make your parsing function run in background (for instance with the Async GCD wrapper) :
func callback(JSON?, response: NSHTTPURLResponse, error: NSError?) {
Async.background {
//Do your JSON parsing stuff here, XXX is a SomeClass object
rows <- rows + [XXX]
}
}
You might have noticed the unusual syntax for the array appending method. That's because making your array "observable" is part of the solution. I advise you to get the Observable-Swift library to make it easier to observe.
Once added to your project, change your array declaration :
var rows = Observable([SomeClass]())
Now implement the method that will be called when your callback parsed a new item (for instance in your viewDidLoad:
)
rows.afterChange += { self.table.reloadData() }
where table
is your table view
If you want to implement a power-friendly runtime, you might want to update the table every time 50 or 100 objects are added to the array. This can be done so (if you want to do so do not implement the method right above):
rows.afterChange += { if $1.count / 100 = 1 { self.table.reloadData() }}
where 100 is the value of new object required to be added in order to update the table. With Observable-Swift, $0 represents the array before it was updated and $1 the array after its update.
One last thing : the rows
array is no longer of type [SomeClass]
but Observable<SomeClass>
. If you want to access the [SomeClass]
value, just replace rows
by rows.value
Hope I didn't misunderstood your question. Anyway if I did, I think that can still help providing a better implementation of JSON parsing.
Upvotes: 1
Reputation: 4016
It's actually a pretty good concern about how you use the resources. Normally, we will go with pagination if you don't want to query back whole amount of data from a request. Then, you will implement some proper logic based on the skip
and limit
in order to get further data.
As for the UITableView
, there is nothing to worry about. Because, it's developed in an efficient way. The total number of cell in memory is the total number of cell visible. The UITableView
will help populating the data via delegation methods. It's not like: you have 500 rows of data, then it has 500 UITableViewCell
. It's reusability.
Upvotes: 0
Reputation: 16793
You should not be worried about how much of data you have to display in TableView. TableView class handles everything for you as long as you pass the json object properly as a Tablesource.
Upvotes: 0