Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Adam Soffer
1,604 PointsUITableView Scrolling is Choppy When Displaying Images From Web
I'm going through the blog reader tutorial series. I've successfully displayed JSON data in my tableview cells, however, while testing the app on my phone I noticed the scrolling feels "choppy". However, if I just set the table cell image using imageNamed:
and load the image from the documents directory, the scrolling is smooth. Why is this? How do I avoid choppy scrolling if I need to populate table cells with images from the web?
Thanks!
11 Answers

Amit Bijlani
Treehouse Guest TeacherAdam Soffer I have created a video explaining how you can asynchronously load data and images using the Blog Reader app as an example. This will help you prevent choppy scrolling.
Video Player

It uses NSURLSession and NSURLSessionDownloadTask

Stone Preston
42,016 Pointsim guessing you are pulling images for each cell in cellForRowAtIndexPath? maybe try downloading all the images beforehand and saving them to an array, and using that array in cell for row instead of downloading them then.

Adam Soffer
1,604 PointsYup I was pulling the image for each cell in cellForRowAtIndexPath. Storing them in an array in viewDidLoad fixed the issue. Thanks Stone!

Aaron Daub
Courses Plus Student 207 PointsThat won't really fix the issue, the fact that it was choppy tells me you're pulling them in on the main thread. You've just moved that problem to viewDidLoad: which could very well slow down the app earlier on. You should look into loading the images asynchronously.

Stone Preston
42,016 PointsAaron Daub makes a good point. You should get them asynchronously. This video from the ribbit app should explain it enough so you can apply it to your situation. It also conveniently deals with getting images.

Adam Soffer
1,604 PointsYup I was pulling the image for each cell in cellForRowAtIndexPath. Storing them in an array in viewDidLoad fixed the issue. Thanks Stone!

Adam Soffer
1,604 Pointswoops :p

kennedy otis
3,570 PointsThis was really helpful.Can this be used in production? Also I have a question concerning NSURLSessionDownloadTask, where you said it downloads to disk..is that data stored permanently there or only when using the the app?

Amit Bijlani
Treehouse Guest TeacherYeah it is something you should be using in production.
From the Apple docs:
"An NSURLSessionDownloadTask object directly writes the response data to a temporary file. Upon completion, the session calls the delegate’s URLSession:downloadTask:didFinishDownloadingToURL: method. In that method, the app must either open the file for reading or move it to a permanent location in its sandbox container directory."

kennedy otis
3,570 PointsThanks that was really a nice lesson. Is it possible to get a lesson on how to create a spinner while waiting waiting for response instead of having a defaults value...

Rashii Henry
16,433 Pointsif you're talking about a pull to refresh control, check out the build a self destructing iPhone App track. Its in one of the videos.

Stone Preston
42,016 Pointsyou could use a UIActivityIndicatorView or a third party library like MBProgressHud

kennedy otis
3,570 PointsMBProgessHud looks good. What I wanted is to know where can I be waiting for the response. same like ajax where you can have a spinner while waiting for data and on arrival you stop the spinner and display the data.

kennedy otis
3,570 PointsI would like to make a music player with external songs which should be loaded from json. My intention is use TableView to display the list of songs and when user clicks a row, then the song at that row should play. I have managed to download the songs using NSURLSessionDownloadTask , which i am not sure if its the right way to do it,.. now issue is to proceed from there and play the songs. Below is my sample and the url contains the songs i would like to fill in my table.
{ status: "OK", tracks: [ { id: 1, name: "Tail Toddle", fileName: "tailtoddle_lo", url: "http://www.tonycuffe.com/mp3/tailtoddle_lo.mp3" }, { id: 2, name: "Sae Will We Yet", fileName: "saewill", url: "http://www.tonycuffe.com/mp3/saewill.mp3" }, ] }
Below is a snippet of how I am download the mp3 songs from the url
//Download the song from TrackURL
if([track.trackURL isKindOfClass:[NSString class]])
{
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[track getTrackURL] completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
});
}];
[task resume];
}
This is the furthest I have reached and am stuck on how to link the songs to the cell. Am using AVAudioPlayer of AVFoundation framework. I will really appreciate any help as am still newbie to ios and not much knowledge.

kennedy otis
3,570 PointsHi guys Would you advice on using the NSURLSession class if your json is only composed of data of type string only.. I mean no heavy files like images,video etc?

michaelspinks
488 PointsQuick question, in cellForRowAtIndexPath you are always creating a download task.... when cells are reused (if you scroll a few cells down) will the app always download the image over and over again? If so surely you should be storing the downloaded image in the sandbox documents folder and then checking if this exists before starting to download the image over and over again.

Amit Bijlani
Treehouse Guest TeacherGreat question. The easiest way to avoid having to download the image all over again is to use a caching library like SAMCache. Once you download the image you cache it and the next time you check the cache first before you download it.

michaelspinks
488 PointsThanks for the very fast answer!
Thomas Nilsen
14,957 PointsThomas Nilsen
14,957 PointsAwesome video. Just one question. Personally when I used this for getting information from a JSON-file to display in a tableView, I used NSURLSessionDataTask. Why would you choose NSURLSessionDownloadTask instead? Both work obviously, but is there a particular advantage one has over the other?
Amit Bijlani
Treehouse Guest TeacherAmit Bijlani
Treehouse Guest TeacherNSURLSessionDownloadTask
downloads the data to disk whereasNSURLSessionDataTask
keeps it in memory. If you are downloading large amounts of data then downloading data to disk makes sense, not mentionNSURLSessionDownloadTask
also supports cancel and resuming of a download.agreatdaytocode
24,757 Pointsagreatdaytocode
24,757 PointsThank you very much for making this video!
Kyle V
781 PointsKyle V
781 PointsThanks! This solved my question and made the scrolling much faster and responsive.
kennedy otis
3,570 Pointskennedy otis
3,570 PointsThe caching suggestion sounds really good.Would like to ask if we can see an example on how to cache the images and how to check from the cache before downloading them. Will really appreciate
Amit Bijlani
Treehouse Guest TeacherAmit Bijlani
Treehouse Guest Teacherkennedy otis We will be launching the "Build a Photo Browser iPhone App" in a couple of weeks that will show you how to do all this in-depth.