Updating tableView on the fly


#1

I decided to beef up my table view a little bit by incorporating thumbnail images into the main table view, and then a larger (170x170) image in the detail view (similar to our implementation in Homepwner.)

Everything works fine (except for the price in the detail view, but I’m not worrying about that part as it seems like a fairly simple issue to fix later.)

My implementation extracts the image URL from the XML document (at first, it’s the 55x55 image), downloads the image and includes a UIImage as part of an object called “Song.” (which includes a method called setAlbumArt - but NOT @synthesized - that accepts the URL, downloads the image, does the conversion, and stores/retains the resulting UIImage.) When creating the table at first, every Song object also stores the URL to the 170x170 image.

The beauty of this approach is that later, once the table is fully loaded, if the user selects a row to show a song detail, the program can check to see if the URL field has data in it. If it does, then it can download the 170x170 image, create a new UIImage, and store it in the AlbumArt field, overwriting the original 55x55 image.

That way, I don’t need to waste a lot of time downloading 10 170x170 images and creating them at first.

–BUT–

It is still taking quite a while to download and create 10 55x55 UIImage objects and store them in the Song object to which they belong; so it dawned upon me that perhaps I could create a UIPopover or something which informs the user that songs are being loaded and parsed. Then it dawned on me that I could, theoretically, update a UILabel in the popover with the entry title currently being worked on.

And that’s where I hit the wall.

Despite sending a setText message to the appropriate UILabel object, the popover just wouldn’t update. I tried dismissing and re-presenting. I also tried dismissing, releasing, re-allocating, and re-presenting. Nothing worked.

Then it dawned on me that I might be thinking too much; and perhaps, instead of a popover, just send a [[self tableView] reloadData]; whenever a song is encountered in the xml data. The idea being as songs are added to the array of songs, then the table could update itself, line by line, so the user sees the list growing.

That didn’t work either.

It seems that the [parser parse]; line blocks operation until parsing is complete. Am I correct in understanding that it also blocks UI updates with [[self tableView] reloadData]; as well?

Or am I missing something else?


#2

Hi,

Yes [parser parse] is blocking the main thread and so no UI updates will get a look in until it’s finished.

You can run the parse operation on a background thread but be warned that updates to the ui need to happen on the main thread so you won’t be able to just add setText or reloadData commands in the usual manner.

See the SeismicXML example app that updates a tableView in batches from a background XML thread.

HTH
Gareth


#3

Thanks for that, Gareth.

I’ve downloaded that sample application, and it’s quite interesting to read through the code. I have a funny feeling I might be delaying progressing on to the next chapter in the book for a small while longer to see if I can incorporate this into my TopSongs application…


#4

Well that was fun!

Using the SeismicXML sample application Gareth pointed me to, I have successfully implemented TopSongs using threading and have got the tableView to update on the fly. This means that the user sees the songs come in to the table one by one, until 10 songs are on the table. As an added bonus, while the data is loading, the networkActivityIndicator little whirly-whirly thing at the top of the screen whizzes around as well.

I’ll post the code if anyone wants…


#5

Nice one - glad it worked out.