SDImageCache unable to retrieve the saved images in Cache - ios

I'm using SDWebImage to store the images in cache and disk memory using a key but while querying using that key i am not getting the images, the code is
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:#"ImageCacheFolder"];
[imageCache queryCacheOperationForKey:[entryidarray objectAtIndex:indexpath.row] done:^(UIImage *image, NSData *data, SDImageCacheType cacheType) {
if (image) {
NSLog(#"image get from cache");
[imageview setImage:image];
} else {
[imageview sd_setImageWithURL:[NSURL URLWithString:imgStr] placeholderImage:[UIImage imageNamed:#"PlaceholderImage-Day"] options:SDWebImageProgressiveDownload];
}
}];
NSURL *url = [NSURL URLWithString:imgStr];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *img = [[UIImage alloc] initWithData:data];
if (img) {
NSLog(#"the image is not nil");
[[SDImageCache sharedImageCache] storeImage:img forKey:[entryidarray objectAtIndex:indexpath.row] toDisk:YES completion:nil];
}else {
NSLog(#"the image is nil");
}

Try this
.
if (img) {
NSLog(#"the image is not nil");
[imageCache storeImage:img forKey:[entryidarray objectAtIndex:indexpath.row] toDisk:YES completion:nil];
}else {
NSLog(#"the image is nil");
}

Related

GoogleDrive file download issue

I am able to download file from GoogleDrive API.
Using the following code.
NSString *url = [NSString stringWithFormat:#"https://www.googleapis.com/drive/v3/files/%#?alt=media",
identifier];
GTMSessionFetcher *fetcher = [self.service.fetcherService fetcherWithURLString:url];
[fetcher beginFetchWithCompletionHandler:^(NSData *data, NSError *error) {
if (error == nil) {
NSLog(#"Retrieved file content");
// Do something with data
UIImage *img = [UIImage imageWithData:data];
NSLog(#"%#", img);
} else {
NSLog(#"An error occurred: %#", error);
[self showErrorAlert:error];
}
}];
It was working fine.(Getting image from data)
Now its not able to compose image.
UIImage *img = [UIImage imageWithData:data];
NSLog(#"%#", img);
Its giving Null.

Updating image and saving it in dictionary

I am getting image as url from dictionary on ViewController A and I have passed that dictionary to ViewController B.I want that if the user has updated the image then it shows the updated image else it shows the previous image and I am doing the following code for it .Kindly check and tell why is it not working as desired and showing the previous image only in every case.
-(void)showUserImage:(NSURL*)imgUrl
{
[ConnectionManager setSharedCacheForImages];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:imgUrl];
NSURLSession *session = [ConnectionManager prepareSessionForRequest];
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
if (cachedResponse.data) {
UIImage *downloadedImage = [UIImage imageWithData:cachedResponse.data];
dispatch_async(dispatch_get_main_queue(), ^{
_profileImageView.image = downloadedImage;
});
} else {
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
if(res.statusCode == 200){
dispatch_async(dispatch_get_main_queue(), ^{
_profileImageView.image = [UIImage imageWithData:data];
});
}
}];
[task resume];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
if(_profileImageView.image == [_detailsDictionary valueForKey:#"ProfilePictureUrl"]) {
NSLog(#"Th url of image is %#",[_detailsDictionary valueForKey:#"ProfilePictureUrl"]);
}
else {
_profileImageView.image = image;
UIImage *updatedImage = _profileImageView.image;
NSData *imageData = UIImageJPEGRepresentation(updatedImage, 100);
NSString *strEncoded = [imageData base64EncodedStringWithOptions:0];
[_detailsDictionary setObject:strEncoded forKey:#"ProfilePictureUrl"];
[self dismissViewControllerAnimated:YES completion:nil];
}
}
#Dirtydanee, He is absolutely correct, you are doing incompatible comparison between Url and UIImage. So please correct this with following code.
NSData *data1 = UIImagePNGRepresentation(previousImage);
NSData *data2 = UIImagePNGRepresentation(currentImage);
if([data1 isEqualToData:data2]) {
//Do something
} else {
//Do something
}
Convert images into NSData and compare the data.
If you want bit-by-bit comparison Please look at the following link:
Generate hash from UIImage
The problem seems to be in this line:
if(_profileImageView.image == [_detailsDictionary valueForKey:#"ProfilePictureUrl"]) {
You are trying to compare the _profileImageView.image, what is UIImage, with [_detailsDictionary valueForKey:#"ProfilePictureUrl"], what is NSURL instance, coming from the dictionary.
What you could do instead, is checking if the picked image and the profileImage is the same.
if(_profileImageView.image == image) {
// etc..
To clear previously cached images, just call:
[[NSURLCache sharedURLCache] removeAllCachedResponses];
Hope this helps!

dispatch_async for getting many images from url

I want to get many images from diffrent url and set it like image's buttons .
I was trying to do this like it's showing above but nothing is happen . When i access this view controller it doesn't have any image for buttons and also neither the banner view is not showed... .
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
NSData *data = [[NSData alloc] initWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^(void){
UIImage *img1 = [[UIImage alloc]initWithData:data];
img2.image = img1;
[bt setBackgroundImage:img2.image forState:UIControlStateNormal];
});
});
I recommend you to use a library that supports cache for images. For instance, I used AFNetworking for one of my projects and it is awesome. And it automatically handles in background for you. In my case I needed a library that automatically cancels a request when I start new one and it worked for me. You can see the code here. And you can see similiar solution from another thread as follows:
AFHTTPRequestOperation *requestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest];
requestOperation.responseSerializer = [AFImageResponseSerializer serializer];
[requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Response: %#", responseObject);
_imageView.image = responseObject;
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Image error: %#", error);
}];
[requestOperation start];
Hope it helps you.
IMHO, you should use async and sync pairs, the inner block should be synchromous to the first one so it will take image when the data is downloaded and available. Also, don;t forget to handle errors:
Try like this:
// Show HUD here
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void)
{
NSError* error;
NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
NSData *data = [[NSData alloc] initWithContentsOfURL:url options:0 error:&error];
dispatch_sync(dispatch_get_main_queue(), ^(void){
if(!error && data)
{
UIImage *img1 = [[UIImage alloc] initWithData:data];
img2.image = img1;
[bt setBackgroundImage:img2.image forState:UIControlStateNormal];
/*
//----OR----
[bt setBackgroundImage:img1 forState:UIControlStateNormal];
*/
}
else
{
// Do error handling here
}
// Hide HUD here
});
});
Hope it helps!
imageView.image = [UIImage imageWithData:yourDefaultImgUrl];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:yourImageUrl];
if (imageData){
dispatch_async(dispatch_get_main_queue(), ^{
imageView.image = [UIImage imageWithData:imageData];
});
}
});
Hope it help.
Try this modification,
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
NSURL *url = [NSURL URLWithString: [pictureUrl objectAtIndex:i]];
NSError *error;
NSData *data = [NSData dataWithContentsOfURL:url options:0 error:&error];
if(error)
{
NSLog(#"Error: %#", [error localizedDescription]);
}
else
{
UIImage *img1 = [[UIImage alloc]initWithData:data];
[bt setBackgroundImage:img1 forState:UIControlStateNormal];
}
// dispatch_async(dispatch_get_main_queue(), ^(void){
//img2.image = img1;
// });
});
Hope it help.
Try this
dispatch_queue_t myQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(myQueue, ^{
NSString *ImageURL = #"yourURL.jpg";
NSData *imageData;
if (ImageURL == nil || ImageURL == (id)[NSNull null] || [[NSString stringWithFormat:#"%#",ImageURL] length] == 0 || [[[NSString stringWithFormat:#"%#",ImageURL] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
{
}
else
{
imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];
}
dispatch_async(dispatch_get_main_queue(), ^{
if (ImageURL == nil || ImageURL == (id)[NSNull null] || [[NSString stringWithFormat:#"%#",ImageURL] length] == 0 || [[[NSString stringWithFormat:#"%#",ImageURL] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
{
imageView.image=[UIImage imageNamed:#"photo_frame_noimage.png"];
}
else if (imageData == nil || imageData == (id)[NSNull null] || [[NSString stringWithFormat:#"%#",imageData] length] == 0 || [[[NSString stringWithFormat:#"%#",imageData] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] == 0)
{
imageView.image=[UIImage imageNamed:#"photo_frame_noimage.png"];
}
else
{
imageView.image=[UIImage imageWithData:imageData];
}
});
});

How to asynchronously download images in ios?

I want to first create imageview onto the scroll view.there i set placeholder image or give Background color of imageview.so all image view are display.
- (void)LoadDataInScrollView
{
dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue",NULL);
//totalImageGetDict into count total Number of object and generate imageview.
for (int ivalue = 0; ivalue < [totalImageGetDict count]; ivalue++)
{
dispatch_async(imageQueue, ^{
//define x value
CGFloat xOrigin =ivalue *ascrollView.frame.size.width+50;
imageView = [[UIImageView alloc] init];
imageView.tag = ivalue;
[imageView setBackgroundColor:[UIColor whiteColor]];
imageView.frame = CGRectMake(xOrigin-40,imgYpos, ascrollView.frame.size.width-20, scrollViewHight);
//then here first i set already downloaded image.it's comes from another class. getImageLoadDict into images are already downloaded**
if ([getImageLoadDict objectForKey:[NSNumber numberWithInteger:ivalue]]!= nil)
{
//dispatch_async(dispatch_get_main_queue(), ^{
[imageView setImage:[getImageLoadDict objectForKey:[NSNumber numberWithInteger:ivalue]]];
//});
}
else
{
//totalImageGetDict into remaining images object and asynchronously download here.
STVisionPhoto *photoObj = [totalImageGetDict objectForKey:[NSNumber numberWithInteger:ivalue]];
UIImage *newimage = [photoObj image];
dispatch_async(dispatch_get_main_queue(), ^{
[imageView setImage:newimage];
});
}
[ascrollView addSubview:imageView];
});
}
}
You can use SDWebImage to do it.It is pretty easy to use
Edit :
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage * image = [UIImage imageWithData:[NSData dataWithContentsOfURL:your url]];
dispatch_async(dispatch_get_main_queue(), ^{
[imgview setImage:image];
});
});
You can try this if you don't want to use any library
Try to use this code:
UIImageView *imgView = [[UIImageView alloc] init];
imgView.frame = CGRectMake(12.5, 12.5, 80, 80);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *profileImage;
profileImage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:YOUR_URL_STRING]]];
dispatch_async(dispatch_get_main_queue(), ^{
imgView.image = profileImage;
});
});
[cell.contentView addSubview:imgView];
(void)loadImg:(NSString *)url img :(UIImageView *)imgView{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
__weak UIImageView *imageV = imgView;
[imgView setImageWithURLRequest:request placeholderImage:[UIImage imageNamed:#"songRecDef"] success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
imageV.image = image;
[imageV setNeedsLayout];
NSLog(#"%#",response);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
[imageV setImage:[UIImage imageNamed:#"songRecDef"]];
NSLog(#"%#",error);
}];
}

How to use SDWebImage in UIWebview

Like we set image in UIImageview using SDWebImage
[imageview.setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}];
Is there any way to use SDWebImage in UIWebview in <img> tag
NSString *htmlString =#"<html lang=\"en\"><img src='http://cdn.tutsplus.com/mobile/uploads/legacy/iOS-SDK_UIView-Animation/Animate-Icon.png' /> </div><div id=\"content\"><div>BlahBlahBlah LoremIpsum</div><br></body>"
[WebView loadHTMLString:descriptionHT baseURL:nil];
Thanks in advance :)
First cache your image:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadWithURL:[NSURL URLWithString:#"http://cdn.tutsplus.com/mobile/uploads/legacy/iOS-SDK_UIView-Animation/Animate-Icon.png"]
options:
0 progress : ^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:
^(UIImage * image, NSError * error, SDImageCacheType cacheType, BOOL finished) {
if (image && finished) {
[[SDImageCache sharedImageCache] storeImage:image forKey:#"icon"];
}
}];
Then when you need the image
__block NSString *imageSource;
__block NSData *imageData = [NSData data];
SDImageCache *imageCache = [SDImageCache sharedImageCache];
[imageCache queryDiskCacheForKey:#"icon" done:^(UIImage * image, SDImageCacheType cacheType) {
imageData = UIImagePNGRepresentation(image);
if (image) {
imageSource = [NSString stringWithFormat:#"data:image/png;base64,%#", [imageData base64Encoding]];
} else {
//start download of image
}
}];
Then in your html:
NSString *htmlString = [NSString stringWithFormat:#"<html lang=\"en\"><img src=\"%#\"/> </div><div id=\"content\"><div>BlahBlahBlah LoremIpsum</div><br></body>", imageSource];
[WebView loadHTMLString:htmlString baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
You don't have to use a key when caching the image, I just thought it made things a little easier.

Resources