How to load images using SDWebImage library - ios

Hi I am using SDWebImage for loading images ok that's fine
Here I am getting images from services and I want to resize those images and I want to load them using SDWebImage
for this I wrote the code below
Obj.imageYH---> this is imageURL
NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:Obj.imageYH]];
UIImage *actualImage = [UIImage imageWithData:imageData];
UIGraphicsBeginImageContext(CGSizeMake(150, 150));
[actualImage drawInRect:CGRectMake(0,0,150, 150)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *smallData = UIImagePNGRepresentation(newImage);
NSString *Finalstring = [[NSString alloc] initWithData:smallData encoding:NSUTF8StringEncoding] ;
[Mainimage sd_setImageWithURL:[NSURL URLWithString: Finalstring] placeholderImage:[UIImage imageNamed:#"collectionViewIcon.png"]];
but in the code above, I am getting null value in Finalstring. How can I resize it and how can I load images using SDWebImage?

Step 1: Installation of SDWebImage
To start with, make sure you're using the latest version of SDWebImage, and installed via CocoaPods (not recommend to link up the library manually).
Your Podfile should contain this line:
pod 'SDWebImage', '~>3.7'
After that, close the Xcode project and run pod install in your project directory. Use the Xcode workspace after installation.
Step 2: Using the codes
First of all, you have the import the library
#import <SDWebImage/UIImageView+WebCache.h>
At this moment, try to Clean & Build the Workspace. If everything goes well, the project should be built without error.
Then, in your function:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:Obj.imageYH
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code, optional.
// You can set the progress block to nil
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// Resize your image here, then set it to UIImageView
Mainimage.image = [UIImage imageWithData:UIImagePNGRepresentation(image) scale:0.5f];
// resize to 0.5x, function available since iOS 6
}
}];
done.

Use below line of codes instead of your code :
UIImage *actualImage = [UIImage imageWithData:imageData];
UIGraphicsBeginImageContext(CGSizeMake(150, 150));
[actualImage drawInRect:CGRectMake(0,0,150, 150)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *smallData = UIImagePNGRepresentation(newImage);
[smallData writeToFile:Finalstring atomically:YES];// Finalstring is file path of resize image
[Mainimage sd_setImageWithURL:[NSURL URLWithString: Finalstring] placeholderImage:[UIImage imageNamed:#"collectionViewIcon.png"]];

SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:url delegate:self options:0 success:^(UIImage
*image) {
cell.profilePicture.image = [self imageByScalingAndCroppingForSize:CGSizeMake(cell.profilePicture.frame.size.width,
cell.profilePicture.frame.size.height) image:image]; } failure:nil];
Don't forget to include
#import <SDWebImage/UIImageView+WebCache.h>
#interface YourViewController : UIViewController <SDWebImageManagerDelegate>

Related

How to set progressive image in iOS using SDWebImage?

I tried to load an image progressively in my app. Basically what I tried is while the image is loading, I want to show the fully loaded image from blurred state. I tried,
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:[NSURL URLWithString:#"https://profile.microsoft.com/RegsysProfileCenter/Images/personal_info.jpg"]
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
[self.profileBtn setImage:[UIImage imageWithData:[NSData dataWithBytes:&receivedSize length:sizeof(receivedSize)] scale:15] forState:UIControlStateNormal];
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// [self.profileBtn setImage:image forState:UIControlStateNormal];
}
}];
Is it possible to load an image progressively using SDWebImage. Please help me with this.
You can try this implementation
+ (void)loadImageWithURLString:(NSString *)urlString forImageView:(UIImageView *)imageView {
[imageView sd_setImageWithURL:[Utilities stringToURL:urlString]
placeholderImage:[UIImage placeHolderImage]
options:SDWebImageProgressiveDownload];
}
The option says that
/**
* This flag enables progressive download, the image is displayed progressively during download as a browser would do.
* By default, the image is only displayed once completely downloaded.
*/
SDWebImageProgressiveDownload = 1 << 3,
You can show percentage of downloading on temp label or below activity indicator (can show activityindicator on image view or button till download is not completed) like in progress block,
NSInteger downloadCompleted = (receivedSize/ expectedSize) * 100;
label.text = downloadCompleted; //temp label on image view or below activityindicator
Hope this will help :)

How to load an image from URL in app Extension?

I have implemented an app extension for my application, but i am facing an issue when trying to load an image from a URL into an imageView.
I tried to use PAImageView and UIImageView but both with failure.
The code that i was using for PAImageView is the following:
[self.imageView setImageURL:[NSURL URLWithString:#"https://blabblaLogo.jpg"]];
self.userImageView.clipsToBounds = YES;
and tried to use SDWebImage for UIImageView with the following:
[self.imageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:#"default.png"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {
}];
and the image doesnt appear in both cases. Note that a default image from assets is displayed correctly without any issue.
Is it possible to load an image from a URL in an app Extension? and how can we achieve that?
Thank you.
Am using something like this and it's work good until this issues fixed
cell.avatar.image = [UIImage imageNamed:#"selection-box_emty.png"];
// Load the image with an GCD block executed in another thread
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:Arr[indexPath.row][#"avatar"]]];
if (data) {
UIImage *offersImage = [UIImage imageWithData:data];
if (offersImage) {
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *offersImage = [UIImage imageWithData:data];
cell.avatar.image = offersImage;
});
}
}
});
I faced a similar problem, put breakpoints into into library and problem apparently was App Tranport Security. We need separate App Transport Security Settings for every extension we add
Try This in your Image url
If image url contain any space it will add %20 and work fine
[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

Loading takes a while when i set UIImage to a NSData with a url.

NSData *imageUrl = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"] ]];
cell.thumbnailImageView.image=[UIImage imageWithData:imageUrl];
this is how i use imageUrl to load them into UIImage but it takes a while to load and the program seems like it crashed or entered to an infinite loop.
How can i make the content of UIImage with url but faster?
I would suggest you to use AsyncImageView a beautiful implementation by Nicklockwood -father of iCarousel.
Link
it is very simple to use.
#import "AsyncImageView.h"
and in all imageViews do this.
[imageView setImage:#"default.png"];
[imageView setImageURL:#"whateverurl/whateverimage.png"];
In your case it would be:
[cell.thumbnailImageView setImageURL:#"yourURL"];
It works like a charm, and my code is in production. But if you still want your code to work try this:
UIActivityIndicator *activity =[[UIActivityIndicator alloc] initWithStyle:UIActivityIndicatorWhite];
[activity setFrame:CGRectMake(0,0,30,30)];
[cell.contentView addSubview:activity];
cell.thumbnailImageView.image=[UIImage imageNamed:#"Default~cell~image.png"];
dispatch_queue_t dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(dispatchQueue, ^(void)
{
[activity startAnimating];
[self loadImages];
dispatch_sync(dispatch_get_main_queue(), ^{
NSData *imageUrl = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"] ]];
cell.thumbnailImageView.image=[UIImage imageWithData:imageUrl]; [activity stopAnimating];
[activty setHidden:YES];
});
});
This happens because every time your cell goes off screen your image is released and if you scroll it back on screen you will have to download your image again. Simply cache your image when downloaded and check if exists use it if not download from internet. You can use third party library like SDWebImage GitHub link
Import SDWebImageView+WebCache.h and in your cellForRowAtIndexPath use the following
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"] placeholder:[UIImage imageNamed:#"placeholder.png"]];
use sdwebimage and down load the library file from here
the few steps you do follow
add the sdwebimage in your project after that
in your .h file
#import "UIImageView+WebCache.h"
in your .m file
call the single line in your cellforRowAtIndexPath
[cell.thumbnailImageView setImageWithURL:[NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"]]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Use an NSOperationQueue so that you can perform the loading of the data on a background thread.
After that you should set the image on the main queue.
// Assume queue is created
[queue addOperationWithBlock:^{
NSData *imageUrl = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"] ]];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
cell.thumbnailImageView.image=[UIImage imageWithData:imageUrl];
}];
}];
For more about NSOperationQueue see the docs about NSOperationQueue.
So try to load image asynchronous.
https://github.com/nicklockwood/AsyncImageView
Use gcd to populate the images,
NSURL *imageUrl = [NSURL URLWithString:[[self.content objectAtIndex:indexPath.row] valueForKey:#"imageUrl"] ]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
UIImage *image = nil;
image = [UIImage imageWithData: [NSData dataWithContentsOfUrl: imageUrl]];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.thumbnailImageView.image = image;
});
})
You will probably want to store the image to some model object, also track if the download has been initiated, since you would not want to queue up the request for the same image url.

Cache UIImage using uitableview from url

I hava a uitableview , with custom cell containing two UImages. The logo images are taken from an online website, that's why there's a need to cache the images. Loading the image till now is made like this :
NSURL * imageURL = [NSURL URLWithString:[arra1 objectAtIndex:indexPath.row / 2]];
NSData * imageData = [NSData dataWithContentsOfURL:imageURL];
NSURL * imageURL2 = [NSURL URLWithString:[arra2 objectAtIndex:indexPath.row / 2]];
NSData * imageData2 = [NSData dataWithContentsOfURL:imageURL2];
cell.ima1.image = [UIImage imageWithData:imageData];
cell.ima2.image2 = [UIImage imageWithData:imageData2];
What i learned from searching , is that dataWithContentsOfURL is not asynchronous , and while scrolling it will take a lot of time. I tried several methods but i can't seem to get to right one. This is my first time caching UIImages , i would highly appreciate a detailed explanation with implementation so i could learn aside from getting the job done.
Many Thanks
I use this Library which is just perfect
SDWebImage
You just need to #import <SDWebImage/UIImageView+WebCache.h> to your project, and you can define also the placeholder when image is being downloaded with just this code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
cell.textLabel.text = #"My Text";
return cell;
}
It also cache downloaded images and gives you great performance.
Hope it will help you!
SDWebImage, in my opinion, is the best option.
You simply include it in your app and use it like this:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:image_url]
options:0
progress:nil
completed:^(UIImage *images, NSError *error, SDImageCacheType cacheType, BOOL complete) {
myImageView.image = images;
}] ;
It download images asynchronously, so it does not block UI.
You can check these sample application
LazyTableImages - Sample application from Apple
MonoTouch-LazyTableImages
robertmryan- LazyTableImages - Explains clearly the limitations from apple's sample application.
Hope this helps.
Checkout UIImageLoader https://github.com/gngrwzrd/UIImageLoader
Easy to load an image, and you get callbacks for all the scenarios you would want to handle:
NSURL * imageURL = myURL;
[[UIImageLoader defaultLoader] loadImageWithURL:imageURL \
hasCache:^(UIImage *image, UIImageLoadSource loadedFromSource) {
//there was a cached image available. use that.
self.imageView.image = image;
} sendRequest:^(BOOL didHaveCachedImage) {
//a request is being made for the image.
if(!didHaveCachedImage) {
//there was not a cached image available, set a placeholder or do nothing.
self.loader.hidden = FALSE;
[self.loader startAnimating];
self.imageView.image = [UIImage imageNamed:#"placeholder"];
}
} requestCompleted:^(NSError *error, UIImage *image, UIImageLoadSource loadedFromSource) {
//network request finished.
[self.loader stopAnimating];
self.loader.hidden = TRUE;
if(loadedFromSource == UIImageLoadSourceNetworkToDisk) {
//the image was downloaded and saved to disk.
//since it was downloaded it has been updated since
//last cached version, or is brand new
self.imageView.image = image;
}
}];

app slowing down due to image load issue

I am having problem with the loading of content in the app, I see that the data is fetched by the app but the images take lot of time to load, is there any possibility to load images afterwords. The code is below:
NSDictionary *dict=[discussionArray objectAtIndex:indexPath.row];
UIImageView *avatarimage = (UIImageView *)[cell viewWithTag:4];
NSString *photoStrn=[dict objectForKey:#"photo"];
dispatch_async(dispatch_get_global_queue(0,0), ^{
NSString *u=[NSString stringWithFormat:#"http://%#",photoStrn];
NSURL *imageURL=[NSURL URLWithString:u];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
dispatch_sync(dispatch_get_main_queue(), ^{
UIImage *dpImage = [UIImage imageWithData:imageData];
if (dpImage==nil)
{
dpImage = [UIImage imageNamed:#"profileImage.png"];
}
avatarimage.image = dpImage;
});
If you want more details I will provide :)
You can use GCD for doing this:
dispatch_async(dispatch_get_global_queue(0,0), ^{
for (NSDictionary *dic in discussionArray)
{
NSString *photoStr=[dic objectForKey:#"photo"];
NSString * photoString=[NSString stringWithFormat:#"http://%#",photoStr];
UIImage *dpImage = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString:photoString]]];
if (dpImage==nil)
{
dpImage = [UIImage imageNamed:#"profileImage.png"];
}
}
});
Get SDWebImage Here and add that in your project and include
UIImageView+WebCache.h
in class implementation file
UIImageView *imag=[[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 40, 40)];
[imag setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#",[[jsonarray objectAtIndex:indexPath.row]valueForKey:#"imgurl"]]] placeholderImage:[UIImage imageNamed:#"Icon#2x.png"]];
[self.view addSubview:imag];
[imag release];
SDWebImage will be more useful for loading images from URL.
Hope this Helps !!!
James,
With this line,
[NSData dataWithContentsOfURL:[NSURL URLWithString:photoString]]]
you make a synchronous network call on the main thread. The current thread will hang untile the network call is complete.
The solution would be to do an asynchronous network call. The AFNetworking library provides a great category to load images asynchronously : UIImageView+AFNetworking.

Resources