0

Despite there are a lot of themes around this topic, I seem very frustrated in the following situation :(

The app downloads and parses a JSON with about 1000 objects, which have in their attributes link for a small image. I need to download (once) these images, store them and use in my TableView as icons.

What is the best way to store such amount of files and to work efficiently with them while displaying the TableView?

Artem Sultan
  • 459
  • 4
  • 10
  • Do you want to download and store these images forever once? Or just once per run? In other words, would you like them in active memory or stored on the disk for later use? – SethHB Sep 28 '12 at 16:07
  • I'd like to store these images...lets say forever. On disk – Artem Sultan Sep 28 '12 at 17:08

2 Answers2

1

I will tell you how will I do it but before I would like to give you a warning about downloading files from the Internet and storing them in your app.

I got one of my apps rejected from Apple lately because I violated rule 2.23 from the App Store Review Guidelines which says:

2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected

Since Apple is using iCloud lately you should minimize the traffic that each app will upload and therefore you should not have more than 40MB stored in your Documents folder of your app. They also say (if you read the links I provided):

Data that can be downloaded again or regenerated should be stored in the /Library/Caches directory.

And since the cache folder can be deleted by the iOS if needed, you should design your app to be prepared to download the images again in case they are gone, so keep this in mind.

Now for my solution, I think downloading 1000 files is too much (even if they are small files). I suggest that you have the files saved in a ZIP file on the server from which you are willing to download and unzip them on your disc once downloaded. This will be much easier and more practical. You can look here to see how to zip and unzip in your app.

After you have your files unzipped I suggest to have a small database (SQLite) from which you can load load the file names, store these names in an array, and then use this array to fill the images in your table in the function cellForRowAtIndexPath.

I hope this helps you. By the way, it is my way to do it but I am not saying it is the "best way" as you are asking :)

Community
  • 1
  • 1
antf
  • 3,162
  • 2
  • 26
  • 33
  • Yep, I also sorted out the problem of working with a bunch of small files (great loss of time while establishing connection ie) its just a bad style... I told this web and android developers, but the issue is that the current version of android client is already working with such structure (I don't know bad or worse but still doing the job)...so I have to deal with tonns of small images :( – Artem Sultan Sep 28 '12 at 19:28
  • Thank you a lot for information!! This might be crucial for my next steps, appreciate a lot...First of all I think I will try to download zip in one run...the other tasks might not involve DB usage...And the last question: What kind of app you fixed with this technique? – Artem Sultan Sep 28 '12 at 19:32
  • First you are welcome. Second, I had a music app where there was a section that shows songs description and a small image in every cell. New songs can be added on the fly and downloaded from the server automatically (sure my app is client-server style). For multiple downloads (but small numbers, 5 to 10 files) I used asynchronous `NSURLConnection`, but for 1000 files you can not do this much asynchronous connections, you need to have them zipped... – antf Sep 28 '12 at 19:43
  • Probably they supposed you're really threatening iTunes)) However this shows the difference! I need that "big" catalog download once at the start of the app and the smaller downloads (not more than 100 i think) in future cases. they are not supposed to be immediate, but the faster the better - noone likes to wait. The volume is not going to be more than 10 mb ...I think the DB usage is odd here - I already have .plist with dictionaries containing details about the object...just need the clear way to deal with images...=| – Artem Sultan Sep 28 '12 at 20:11
0

Given that you would like to keep these images/data persistent, you now have two options: You can manage them yourself or you can utilize Core Data to help you do it. I recommend Core Data.

If your not familiar with Core Data, you can start reading about it Here. It's a little bit daunting to get started, but once you've run through a tutorial it's extremely straightforward and will make your life much easier.

If you would like store the images yourself, or would like a more efficient Core Data structure, I recommend writing all of your images into your Documents directory as see Here. Then you can just store File path strings in your CD structure or manually in your plist like This.

And finally, for loading them into your TableView you can use those stored image paths to load UIImages with:

[[UIImage alloc] initWithContentsOfFile:filePath];

This would be placed within your:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

function so that you can set the image where you would like.

Community
  • 1
  • 1
SethHB
  • 743
  • 4
  • 12
  • Thanks! I suppose the main problem is downloading here...If they are saved in Documents directory, wouldn't that be Ok for such amount of files? – Artem Sultan Sep 28 '12 at 19:36
  • Once you've managed to download the files, there is no limit to how many you can have in your Documents directory. Using Core Data to manage the file paths and other meta data will allow you to only load the ones you need currently. – SethHB Sep 28 '12 at 22:58