If you're pulling in web data such as images that doesn't change but needs to be viewed multiple times, you'll want to cache it. Caching images dramatically improves the performance of scrolling tables and other views.
Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.
I guess I thought it was pretty self explanatory, but then again I wrote it . I've got enough comments in there (I think) to explain each piece - explaining code line by line is a little over the top. I also broke each function into it's own section.
I'm a bit of an Objective-C noob myself so I thought it would be nice to post helpful pieces of code that the community might benefit from.
I guess I thought it was pretty self explanatory, but then again I wrote it . I've got enough comments in there (I think) to explain each piece - explaining code line by line is a little over the top. I also broke each function into it's own section.
I'm a bit of an Objective-C noob myself so I thought it would be nice to post helpful pieces of code that the community might benefit from.
Thats great! Thanks .
And yes, it is nice to post helpful pieces of code for the community.
Hey first off - thanks so much for your example- I'm very new to obj C and IPhone dev and found this utility to be very useful. Caching is such a common task.
Some brief questions and suggestions:
1> Where does the file go? What about cleanup, I'd hate to cache a few hundred images and then leave them in limbo?
I did a NSLOG and see the file goes here...
/var/folders/RJ/RJWwAcBZFtC36gaSUm0wKU+++TI/-Tmp-/ad.jpg
I tried to use finder to actually find the file to delete it, so I can test it again.
Suggestions or maybe post some additional help to extend the utilities class with two additional method (clearImage) to have a clear a single image (by filename) or the entire image cache (clearImageCache) ?
BTW - I updated your original code to take a filename arg. It seemed like you'd want a handle on that - for doing things like the forementioned cleanup..
Finally - here's an example of how to create and call your class:
// Assumes you've included the class in the header.
// ImageName is the url of an image (NSSTRING)
//imgView is the image (UIImageView)
I am just wondering if there is a reason why you didn't just call the write function of the data from the url? If you do this then there will be support for all types of images. Below is some sample code demonstrating this.
Currently its taking me 0.8seconds for each image that i get from the server so if i cache 1000 images and then search for one to load, will it take more time to load than 0.8? I am currently running my app in simulator
Thats great! Thanks .
And yes, it is nice to post helpful pieces of code for the community.
Hey steaps, how can i clear this cache everytime I close my app? I am doing this in simulator and its perfectly working for me. But I can see that even the next time when I come, its still there. So what should I do to clear the cache when I close?
Hey steaps, how can i clear this cache everytime I close my app? I am doing this in simulator and its perfectly working for me. But I can see that even the next time when I come, its still there. So what should I do to clear the cache when I close?
This is the reason why I used another approach. Instead of using TMP system directory, I create my own "tmp" directory in the Documents folder. I write there my cached file, and when I close the app in -applicationWillTerminate in the AppDelegate I delete that folder.
Well this is all cool, but I don't think it's good in most cases. iPhone ships with NAND Memory built in which slowly dies-as-you-readwrite. I found good approach in "Advanced iPhone Projects" published Apress:
Quote:
With the iPhone’s NAND flash memory, writing is expensive both in terms of speed and in terms of hardware lifetime. It will eventually wear out with use. Apple recommends that you write to disk only when necessary. Since our application checks to see whether the data is stale, it is unlikely to download stock data more than once or twice per day, so you can reasonably store it to disk when it arrives. If your data were more often malleable, you might consider storing it only when the application closes or if you ran out of memory. In gogoDocs[Their App], we only download and write the updated feed if its last changed date is later than that of our cached information. This keeps the application from making unnecessary writes to the flash memory. Apple supplies a convenience method in your application’s delegate where you can save data before the app closes:
If you can cache images, can you also cache results from a sqlite database? I'm building an app with "football players" and there can be potentially thousands of records.
If you can cache images, can you also cache results from a sqlite database? I'm building an app with "football players" and there can be potentially thousands of records.
cache results from sqlite?
sqlite is a database, there is no motive to cache a result from a database, generally a query need only few milliseconds.
for example, also with 100,000 records, derive the data (40-50 entry?) from a ID of a player, would take approximately less than 1 second.
// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
NSLog(@"Cashe");
image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
}
else
{
// get a new one
Thank you for your reply...i tried what you said..i did'nt get error but its still same.. ....
The "Filename" string you are using to get the "UniquePath" must be unique itself. It must correspond to the filename of image you have cached. As you have it now all of the images are being cached under the filename "haberler3", so when you are retrieving the images it is always pointing to the same image. Give each image you want to cache a unique filename.
try this:
Code:
- (void) cacheImage: (NSString *) ImageURLString imageName:(NSString*)imageName
{
NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
// Generate a unique path to a resource representing the image you want
NSString *filename = imageName;
NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
// Check for file existence
if(![[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
// The file doesn't exist, we should get a copy of it
// Fetch image
NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
UIImage *image = [[UIImage alloc] initWithData: data];
// Do we want to round the corners?
image = [self roundCorners: image];
// Is it PNG or JPG/JPEG?
// Running the image representation function writes the data from the image to a file
if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImagePNGRepresentation(image) writeToFile: uniquePath atomically: YES];
}
else if(
[ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound ||
[ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound
)
{
[UIImageJPEGRepresentation(image, 100) writeToFile: uniquePath atomically: YES];
}
}
}
- (UIImage *) getCachedImage: (NSString *) ImageURLString imageName:(NSString*)imageName
{
NSString *filename = imageName;
NSString *uniquePath = [TMP stringByAppendingPathComponent: filename];
UIImage *image;
// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
image = [UIImage imageWithContentsOfFile: uniquePath]; // this is the cached image
}
else
{
// get a new one
[self cacheImage: ImageURLString imageName:imageName];
image = [UIImage imageWithContentsOfFile: uniquePath];
}
return image;
}
and insert a different "imageName" for each image you want to cache.
i finnally managed it to work...but it didn't work the way i though... Scrolling is laggy at first scroll...('till images downloaded) . i want images to be downloaded at start-up. Anyway, you were so helpfull... Thank you..
hey, I have made a class file I plan on uploading to github,would you mind if I use your methods in the class file?
Thanks
Quote:
Originally Posted by chewbocka
If you're pulling in web data such as images that doesn't change but needs to be viewed multiple times, you'll want to cache it. Caching images dramatically improves the performance of scrolling tables and other views.
Note: this only works for JPG and PNG images. If you have suggestions or find bugs, let me know.