Adding images Asynchronously - ASIHTTPRequest - iphone

I am using ASIHTTPRequest. I have the following issues while using ASIHTTPRequest.
1.) I need to add images to UITableView (for each cell) asynchronously. How can i do this ?
2.) I need to add an image to a UIViewController Asynchronously. (Not to a cell, but just on the UIImageView, which is on a UIViewController).
Can someone please help me with some sample code, Example or a Tutorial to start with?

No need to introduce a dependency to a whole framework such as ASIHTTPRequest just to download one image, when you can do it a few easy lines of code using GCD:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageDate = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
avatar.image = image;
});
});
This is asynchronous and all the goodness. But in a few lines of code you can write, understand, bug-fix, extend and maintain yourself.
But in case you are bent on using ASIHTTPRequest I suggest using this excellent project Here is a sample code to have a guide line and a brief description.
One other way is that you can use the asynchronous image view instead of the default image view. check tutorial Here and also How? UITableViewCell with UIImageView asynchronously loaded via ASINetworkQueue

Basically (see example page with all the correct syntax) what you do is
Create a request.
Set yourself as a delegate for when it's complete.
Start the request.
In -(void)requestFinished: you add the image to your TableView as you would in normal code.

I'm not sure that it's exactly what you are looking for, but check out the lazy image loading example from apple. But they use NSURLConnection.
Hope it helps

Related

Loading Images From A URL(nsurlconnection)

I have to Implement a UITableView that should display all hosted photos. Load the photos synchronously and asynchronously in different tabs.
how to call images from url??
To load an image from a url:
NSData *imageData = [NSData dataWithContentsOfURL:yourURL];
UIImage *image = [UIImage imageWithData:imageData];
You can use GCD to perform the actions asynchronously. There's a good tutorial of almost exactly what you're trying to achieve here
You can used the Apple TableView Lazy Loading. They have sample codes that download images asynchonously to avoid freeze of UI. See link below
Apple LazyTableImages

SDWebImage - how to load image from Cache?

I use SDWebImage to download images into my UITableView using:
[cell.imageView setImageWithURL:[NSURL URLWithString:tempPhotoURL] placeholderImage:[UIImage imageNamed:#"temp.jpg"]];
This works perfectly - no problem there. But when I click on any given row in my TableView, I want to load that row's thumbnail-image into a UIImageView that's sitting in the oncoming detail-screen to which I'm navigating. Well how do I do this? Do I now have to get the image from the cache since its already been downloaded? If so, what's the method/process for this? And if that's not the way to go, what is?
I can't figure it out from all those files and methods included in the SDWebImage library...
Simply use almost exactly same code to set the image - SDWebImage will check if it is already cached and if so, it will use it instead of fetching image from the url.
Try this,
[self.imgView sd_setImageWithURL:[NSURL URLWithString:imageUrl placeholderImage:placeholderUrl options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {
//Progress block
} completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL){
//Completion block
}];
There are many ways to achieve things when coding.
One that springs to mind is to ensure the UIImageView is an accessible property of your detail view controller (part of the detail view controller's API).
Then all you need to do is before you push your detail view controller, assign the cell's image view to the detail view's UIImageView property.
OR
create a convenience initialiser and pass the cell's imageview to it...
etc etc.
Call the same method, you downloaded with in your TableView in DetailView when you set the picture, it will check the cache first. Here's the code snippet to download image with SDWebImage
[yourImageView sd_setImageWithURL:[NSURL URLWithString:yourImageUrl]
placeholderImage:[UIImage imageNamed:#"placeholder.jpg"]];

Asynchronous images - Meant for displaying images from web only?

I have images in my documents folder which I am displaying on one of my screens. It takes times to load the images and display them on the screen similar to when loading images from web. As far as I know asynchronous imageView works for the later case. I might be wrong.
Is there anyway we can display images from documents folder asynchronously?
Take a look at SDWebImage. It is a UIImageView subclass that lets you display image asynchronously from a URL and with a useful cache. It is designed to work with Internet URLs, but I think it will also go with internal URLs.
Put the loading of images in the background thread as following
-(void)backgroundLoadImageFromPath:(NSString*)path {
UIImage *newImage = [UIImage imageWithContentsOfFile:path];
[myImageView performSelectorOnMainThread:#selector(setImage:) withObject:newImage waitUntilDone:YES];
}
Then call that thread wherever you need to set the image
[self performSelectorInBackground:#selector(backgroundLoadImageFromPath:) withObject:path];
Note, in backgroundLoadImageFromPath you need to wait until the setImage: selector finishes, otherwise the background thread's autorelease pool may deallocate the image before the setImage: method can retain it.

UIImage in uitableViewcell slowdowns scrolling table

I am loading image with data in my table view. Images are coming from web. I created method to get image url in model class.Model class has Nsdictionary and objects.
But this images is slowing down scrolling .Here is my code
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",
[(Tweet *)[recentTweets objectAtIndex:indexPath.row]urlString]]]]];
cell.imageView.image = image;
Please tell Where I am going wrong?
Use lazy loading and do your own drawing. Try to understand the techniques on the sample projects I linked. These are the best ways to improve the performance of tables with images.
here is the methodology I use for loading images into a UITableView from a remote location:
in your .h file, declare a mutable dictionary for storing the images:
NSMutableDictionary *images;
initialize the dictionary in -init... or in -viewDidLoad
images = [[NSMutableDictionary alloc]init];
in the .m, tableView:cellForRowAtIndexPath:, see if the image exists in your dictionary for the indexPath
UIImage *img = [images objectForKey: indexPath];
if the image does exist, just set it.
if (img) cell.imageView.image = img;
if the image does NOT exist, set the cell's image to a temporary image...
if (!img) cell.imageView.image = [UIImage imageNamed:#"imageUnavailable.png"];
AND add that image to your dictionary so it doesnt try to refetch the image if you scroll off and back to that image before it loads...
[images setObject:[UIImage imageNamed:#"imageUnvailable.png"] forKey: indexPath];
then, in this same block, use an NSOperationQueue, and a custom NSOperation ( here is a reference - NSOperation and SetImage) to get your image and call back into your UITableViewController with that image.
in your callback, add your image to the dictionary (overwriting the temp image) and call [tableView reloadData]
this will give you a nice non blocking user experience.
The are a couple of ways how to do it. I had the best experience with a Queue for the HttpRequests, which I pause during the scrolling process.
I highly recommend this framework for that:
http://allseeing-i.com/ASIHTTPRequest/
I also implemented an image cache, which only loads the images if there weren't in the cache.
And the last tweak was to actually draw the images instead of using a high level uicomponent like the UIImageView
The number one reason your code is slow right now is because you're making a network call on the main thread. This blocks an UI from being updated and prevents the OS from handling events (such as taps).
As already suggested, I recommend ASIHTTPRequest. Combine asynchronous requests with an NSOperationQueue with a smaller concurrency count (say, 2) for the image requests, caching, and reloading the rows when images come in (on the main thread) (also only reloading the row if its currently visible). You can get a smooth scrolling table view.
I have an example of this on github here: https://github.com/subdigital/iphonedevcon-boston
It's in the Effective Network Programming project and includes a set of projects that progressively improve the experience.
Download the images before you load the tableView, and store them in an NSArray. Then when the cellForRowAtIndexPath method is called, show a loading image until the image is in the array.

How to fetch images for every UiTableViewCell efficently?

I receive and parse JSON from the internet in my app delegate. In JSON there are links to images that must be displayed in table cells (1 image per cell).
If i fetch images in cellForRowAtIndexPath method, it takes quite some time to load the whole view. I use this code in cellForRowAtIndexPath:
NSURL *url = [NSURL URLWithString:imageUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
cell.imageView.image = [UIImage imageWithData:data];
How should i fetch these images without slowing down application launch (where should i put my code)?
I read a few things about NSOperation, is this the right way to go?
Tnx.
you can implement lazy loading
try this out
http://kshitizghimire.com.np/lazy-loading-custom-uitableviewcell/
or you can check apple's example
http://developer.apple.com/library/ios/#samplecode/LazyTableImages/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009394
good luck
Create class to download the Images. After downloading the Image you can Implement a delegate method. In the Delegate method Reload the cell with corresponding images.