NSOperationQueue Issue - ios

I have a code that i used as a image downloder in ios 6 but when i use same code in different application that used ios 5 it gives me error NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance hear is the code that i am using
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl = [NSURL URLWithString:ImageURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *images = nil;
if (imageData)
images = [UIImage imageWithData:imageData];
if (images){
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
Can anybody tell me what i am doing wrong coz this code is help me a lot when downloading image separately. Thank you
PS Whole function that i am using
-(void) setScrollView:(UIScrollView *)scrollview :(NSArray *)contentArray{
int x = 0;
int i = 0;
NSString *ImageURL=#"http://www.online-image-editor.com/styles/2013/images/example_image.png";
for(NSDictionary *str in contentArray){
UIImageView *imageV = [[UIImageView alloc ] initWithFrame:CGRectMake(x, 0, 200,125)];
#try {
ImageURL = [str objectForKey:#"image"];
}
#catch (NSException * e) {
NSLog(#"Exception: %#", [e description]);
}
imageV.userInteractionEnabled = YES;
ImageTapGesture *singleTap = [[ImageTapGesture alloc] initWithTarget:self action:#selector(tapDetectedMain:)];
singleTap.newItem = str;
singleTap.currentItem = i ;
singleTap.numberOfTapsRequired = 1;
[imageV addGestureRecognizer:singleTap];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(x,125,200,20)];
[title setFont:[UIFont systemFontOfSize:11]];
title.numberOfLines = 2;
title.autoresizingMask = UIViewAutoresizingFlexibleHeight;
[title setBackgroundColor:[UIColor blackColor]];
[title setTextColor:[UIColor whiteColor]];
title.text = [NSString stringWithFormat:#" %#",[str objectForKey:#"title"]];
x += title.frame.size.width+2;
UIImage *cachedImage = [self.imageCache objectForKey:ImageURL];
if (cachedImage){
imageV.image = cachedImage;
}
else{
imageV.image = [UIImage imageNamed:#"vdo.png"];
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl = [NSURL URLWithString:ImageURL];
NSData *imageData = [NSData dataWithContentsOfURL:imageUrl];
UIImage *images = nil;
if (imageData)
images = [UIImage imageWithData:imageData];
if (images){
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
}
[scrollview addSubview:imageV];
[scrollview addSubview:title];
}
scrollview.contentSize = CGSizeMake(x, scrollview.frame.size.height);
i++;
}

You should definitely check the ImageURL you are sending into the operation. It seems, this ImageURL is [NSNull null].
If it is a local variable, is it declared as __block NSString *ImageUrl?

pls try this code:
[self.imageDownloadingQueue addOperationWithBlock:^{
NSURL *imageUrl ;
if((ImageURL!=nil)&&(![ImageURL isKindOfClass:[NSNull class]]))
{
imageUrl= [NSURL URLWithString:ImageURL];
}
NSData *imageData;
if((imageUrl!=nil)&&(![imageUrl isKindOfClass:[NSNull class]]))
{
imageData = [NSData dataWithContentsOfURL:imageUrl];
}
UIImage *images = nil;
if((imageData!=nil)&&(![imageData isKindOfClass:[NSNull class]]))
images = [UIImage imageWithData:imageData];
if((images!=nil)&&(![images isKindOfClass:[NSNull class]]))
{
[self.imageCache setObject:images forKey:ImageURL];
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// make sure the cell is still visible
imageV.image = images;
}];
}
}];
Hope this will help you.

Related

Need to set the image from URL without any blink. Read the description to know the complete scenario

I am uploading the image from the ImagePicker and once the image is upload on the server I show it from URL. So from local image to URL image, there comes a blink, which I want to avoid but I am unable to fix it. Any suggestion will be really helpful. I am adding the code below:
- (void)setDataOnCell:(NSDictionary *)dict {
self.messageTimeLabel.text = [CommonUtils checkForNUllValue:[dict valueForKey:#"msg_time"]];
if (![[CommonUtils checkForNUllValue:[dict valueForKey:#"msg_status"]] isEqualToString:#"Read"]) {
self.messageTickImageView.image = [UIImage imageNamed:#"check_delivered_icon"];
self.messageStatusLabel.textColor = [UIColor colorWithRed:166.0f/255.0f green:166.0f/255.0f blue:166.0f/255.0f alpha:1.0];
}
else {
self.messageTickImageView.image = [UIImage imageNamed:#"check_read_icon"];
self.messageStatusLabel.textColor = [UIColor colorWithRed:254.0f/255.0f green:223.0f/255.0f blue:224.0f/255.0f alpha:1.0];
}
self.messageStatusLabel.text = [CommonUtils checkForNUllValue:[dict valueForKey:#"msg_status"]];
if ([[NSString stringWithFormat:#"%#", [dict valueForKey:#"attachment_type"]] isEqualToString:#"local_img"]){
self.messageImageview.image = [dict valueForKey:#"attachment"];
}
else {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#", [NSString stringWithFormat:#"%#", [dict valueForKey:#"attachment"]]]];
NSData *urlData = [NSData dataWithContentsOfURL:imageURL];
//This is your completion handler
dispatch_sync(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:urlData];
self.messageImageview.image = image;
});
});
}
}
first of all you need to set a default image on this image view after that you call image by url and set on this
NSOperationQueue *queueThumbnl = [[NSOperationQueue alloc] init];
[queueThumbnl setMaxConcurrentOperationCount:NSOperationQueueDefaultMaxConcurrentOperationCount];
[queueThumbnl addOperationWithBlock:^{
// Background work
NSURL *imageURL = [NSURL URLWithString:[NSString stringWithFormat:#"%#", [NSString stringWithFormat:#"%#", [dict valueForKey:#"attachment"]]]];
NSData *urlData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:urlData];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:self.messageImageview, #"messageImageview", urlData, #"imageData", nil];
[self performSelectorOnMainThread:#selector(mainThreadUIUpdate:) withObject:dict waitUntilDone:YES];
// [self updateThumbnailOnMainThread:anItem setImageTo:cell];
}];
-(void)mainThreadUIUpdate:(NSDictionary *)dict
{
UIImageView *messge = [dict objectForKey:#"messageImageview"];
UIImage *image = [dict objectForKey:#"image"];
[messge.imageView setImage:image];
[cell.imageView setNeedsDisplay:YES];
}

How to save URL images to a gallery in IOS

I have an array of images coming from sever. I have a button to save it to gallery. The images coming from server are in url form. Now i want to download the image which i select from an array. I have a button when then image opens in larger view, but the code is used is not working.
Code,
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayOfImages = [userDefaults objectForKey:#"property_images"];
NSLog(#"GGG %#",arrayOfImages);
self.imagesData=[[NSArray alloc]init];
self.imagesData = arrayOfImages;
NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES) objectAtIndex:0];
for (UIImageView *imageViewToSave in self.imagesData){
NSInteger tag = imageViewToSave.tag;
UIImage *image = imageViewToSave.image;
NSString *imageName = [NSString stringWithFormat:#"Image%li.png",(long)tag];
NSString *imagePath = [docsDir stringByAppendingPathComponent:imageName];
// Log the image and path being saved. If either of these are nil, nothing will be written.
NSLog(#"Saving %# to %#", image, imagePath);
[UIImagePNGRepresentation(image) writeToFile:imagePath atomically:NO];
}
NSLog(#"Save Button Pressed");
This is how we can show image on tap gesture,
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayOfImages = [userDefaults objectForKey:#"property_images"];
NSLog(#"GGG %#",arrayOfImages);
self.imagesData=[[NSArray alloc]init];
self.imagesData = arrayOfImages;
NSLog(#"Image Array is %#",_imagesData);
//dispatch_group_t group = dispatch_group_create();
for(int i=0; i<self.imagesData.count;i++){
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.view.frame) * i, 0, CGRectGetWidth(self.view.frame), CGRectGetHeight(self.scrollView.frame))];
imageView.contentMode = UIViewContentModeScaleAspectFill;
[imageView sd_setImageWithURL:[NSURL URLWithString:[self.imagesData objectAtIndex:i]]
placeholderImage:[UIImage imageNamed:#"launch.png"]];
// imageView.image = [UIImage imageNamed:[self.imagesData objectAtIndex:i]];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:#selector(expandImage:)];
tap.numberOfTapsRequired = 1;
imageView.tag = i;
NSLog(#"KK %ld",imageView.tag);
[imageView setUserInteractionEnabled:YES];
[imageView addGestureRecognizer:tap];
[self.scrollView addSubview:imageView];
// dispatch_group_enter(group);
[imageView sd_setImageWithURL:[NSURL URLWithString:[self.imagesData objectAtIndex:i]] placeholderImage:nil options:SDWebImageHighPriority completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
//dispatch_group_leave(group);
}];
_fullImage.hidden=NO;
_fullView.hidden=NO;
}
The method for expand is this,
-(void)expandImage:(UITapGestureRecognizer*)recogniser
{
// _fullImage.image = [UIImage imageNamed:[self.imagesData objectAtIndex:recogniser.view.tag]];
[_fullImage sd_setImageWithURL:[NSURL URLWithString:[self.imagesData objectAtIndex:recogniser.view.tag]]
placeholderImage:[UIImage imageNamed:#"launch.png"]];
NSLog(#"RRR %#",self.imagesData);
NSLog(#"TTT %ld",recogniser.view.tag);
}
You can use this function:
UIImageWriteToSavedPhotosAlbum(UIImage *image,
id completionTarget,
SEL completionSelector,
void *contextInfo);
completionTarget, completionSelector and contextInfo all notified when the UIImage is done saving if not use this all then you can pass nil.
like.
UIImageWriteToSavedPhotosAlbum(your UIImage, nil, nil, nil);

UITableView, Its jerking while scrolling

/Problem is that, I created my own contentviews in UITableview and showing. While scrolling the table view is giving Jerking. How to resolve this issue./
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
/ImageDetails, I am receiving from server and loading using lazy loading./
UIImageView *lblImage = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 60, 60)];
lblImage.contentMode = UIViewContentModeScaleAspectFill;
[cell.contentView addSubview:lblImage];
if([[[lArray objectAtIndex:indexPath.row] objectForKey:#"Foto"] length] > 0){
NSURL *imageURL = [NSURL URLWithString:[[lMovikidListArray objectAtIndex:indexPath.row] objectForKey:#"MovikitFoto"]];
NSString *key = [[[lArray objectAtIndex:indexPath.row] objectForKey:#"Foto"] MD5Hash];
NSData *data = [FTWCache objectForKey:key];
if (data) {
UIImage *image = [UIImage imageWithData:data];
lblImage.image = image;
} else {
lblImage.image = [UIImage imageNamed:#"defaultprofile.png"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
[FTWCache setObject:data forKey:key];
UIImage *image = [UIImage imageWithData:data];
dispatch_sync(dispatch_get_main_queue(), ^{
lblImage.image = image;
});
});
}
CALayer *imageLayer = lblImage.layer;
[imageLayer setCornerRadius:lblImage.frame.size.width/2];
[imageLayer setMasksToBounds:YES];
}
else{
lblImage.image = [UIImage imageNamed:#"defaultprofile.png"];
}
UILabel *lblTitle = [[UILabel alloc]initWithFrame:CGRectMake(75, 10, 220, 25)];
lblTitle.text = [NSString stringWithFormat:#"%# - %#", [[lArray objectAtIndex:indexPath.row] objectForKey:#"Name"], [[lArray objectAtIndex:indexPath.row] objectForKey:#"SimNo"]];
lblTitle.font = [UIFont boldSystemFontOfSize:14.0f];
[cell.contentView addSubview:lblTitle];
UILabel *lblSubTitle = [[UILabel alloc]initWithFrame:CGRectMake(100, 40, 195, 35)];
if([[[lArray objectAtIndex:indexPath.row] objectForKey:#"Location"] length] <= 1){
lblSubTitle.text = LOCATION_NOT_AVAILABLE;
lImageName = #"caution_icon.png";
}
else{
lblSubTitle.text = [self calculateDistance:<some data>];
}
lblSubTitle.textColor = [UIColor darkGrayColor];
lblSubTitle.numberOfLines = 2;
lblSubTitle.font = [UIFont italicSystemFontOfSize:12.0f];
[cell.contentView addSubview:lblSubTitle];
/This image is a small image to show some indicators./
UIImageView *lblIndicatorImage = [[UIImageView alloc]initWithFrame:CGRectMake(75, 45, 20, 20)];
lblIndicatorImage.image = [UIImage imageNamed:lImageName];
[cell.contentView addSubview:lblIndicatorImage];
[cell setNeedsDisplay];
You cant do any UIKit operation on background thread. So just remove your graphical operation from background thread and it will be fine.
else {
lblImage.image = [UIImage imageNamed:#"defaultprofile.png"];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:imageURL];
[FTWCache setObject:data forKey:key];
dispatch_async(dispatch_get_main_queue(), ^{
UIImage *image = [UIImage imageWithData:data];
lblImage.image = image;
});
});

Convert NSData To UIImage

First of all I am selecting some images in one listingstep1view and passing those UIImages other View Controller by using sharedInstance.
ListingStep1Viewcontroller:
- (void)elcImagePickerController:(ELCImagePickerController *)picker didFinishPickingMediaWithInfo:(NSArray *)info
{
[self dismissViewControllerAnimated:YES completion:nil];
for (UIView *v in [_scrollView subviews]) {
[v removeFromSuperview];
}
NSLog(#"info :%#", info);
CGRect workingFrame = _scrollView.frame;
workingFrame.origin.x = 0;
NSMutableArray *tempArray =[[NSMutableArray alloc] init];
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[info count]];
for (int i =0; i<info.count; i++) {
NSDictionary *dict = [info objectAtIndex:i];
if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypePhoto){
if ([dict objectForKey:UIImagePickerControllerOriginalImage])
{
UIImage* image = [dict objectForKey:UIImagePickerControllerOriginalImage];
[iPhoneXMPPAppDelegate load_uploadingImage:[image fixOrientation]];
NSData* data = UIImageJPEGRepresentation([iPhoneXMPPAppDelegate get_upload_image], 1.0f);
//NSString *encodedImage = [data base64Encoding];
[Base64 initialize];
self.convertedImage=[[UIImage alloc]initWithData:data];
//self.convertedImage=[UIImage imageWithData:data];
NSLog(#"converted Data To Image= %#",self.convertedImage);
NSString *strEncoded = [Base64 encode:data];
strEncoded = [strEncoded stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
[tempArray addObject:strEncoded];
[images addObject:image];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
[_scrollView addSubview:imageview];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
} else {
NSLog(#"UIImagePickerControllerReferenceURL = %#", dict);
}
}
else if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypeVideo){
if ([dict objectForKey:UIImagePickerControllerOriginalImage]){
UIImage* image=[dict objectForKey:UIImagePickerControllerOriginalImage];
[images addObject:image];
UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
[imageview setContentMode:UIViewContentModeScaleAspectFit];
imageview.frame = workingFrame;
[_scrollView addSubview:imageview];
workingFrame.origin.x = workingFrame.origin.x + workingFrame.size.width;
} else {
NSLog(#"UIImagePickerControllerReferenceURL = %#", dict);
}
} else {
NSLog(#"Uknown asset type");
}
}
self.chosenImages = images;
[[ListingStep2Model sharedInstance]setImagesAssetArray:tempArray];
//[[ListingStep2Model sharedInstance]setConvertedImage:self.convertedImage.image];
[_scrollView setPagingEnabled:YES];
[_scrollView setContentSize:CGSizeMake(workingFrame.origin.x, workingFrame.size.height)];
}
ListingStep5viewcontoller:
for (int i = 0; i < [[[ListingStep2Model sharedInstance] imagesAssetArray]count]; i++) {
NSMutableArray *images = [NSMutableArray arrayWithCapacity:[[[ListingStep2Model sharedInstance] imagesAssetArray]count]];
//UIImage*imageTodata=[[ListingStep2Model sharedInstance] convertedImage];
NSLog(#"Data Imges:%#", [[[ListingStep2Model sharedInstance] imagesAssetArray] objectAtIndex:i]);
//NSLog(#"Data Imges:%#", imageTodata);
NSDictionary *dict;
if ([dict objectForKey:UIImagePickerControllerMediaType] == ALAssetTypePhoto){
if ([dict objectForKey:UIImagePickerControllerOriginalImage])
{
{
UIImage* image = [dict objectForKey:UIImagePickerControllerOriginalImage];
[iPhoneXMPPAppDelegate load_uploadingImage:[image fixOrientation]];
NSData* data = UIImageJPEGRepresentation([iPhoneXMPPAppDelegate get_upload_image], 1.0f);
//UIImageView *imgv = [[UIImageView alloc]init];
[Base64 initialize];
NSString *strEncoded = [Base64 encode:data];
strEncoded = [strEncoded stringByReplacingOccurrencesOfString:#"+" withString:#"%2B"];
NSMutableDictionary *param = [NSMutableDictionary dictionary];
[param setObject:strEncoded forKey:[NSString stringWithFormat:#"image%d",i]];
}
} else {
NSLog(#"UIImagePickerControllerReferenceURL = %#", dict);
}
}
}
[iPhoneXMPPAppDelegate startIndicator];
NSMutableArray *totalrequest = [[NSMutableArray alloc] init];
[totalrequest addObject:param];
[RequestAndResponseHandlers helparucommonRequestAndResponseHandlerWithParam:[NSDictionary dictionaryWithObjectsAndKeys:totalrequest,#"request",nil] methodName:methodName completionHandler:^(NSDictionary *response) {
NSLog(#"Response :%#", response);
if ([[response valueForKeyPath:#"response.httpCode"] integerValue]==200) {
[[iPhoneXMPPAppDelegate appdelegate] navigateTo:[iPhoneXMPPAppDelegate publicView ]];
}
else {
[iPhoneXMPPAppDelegate alertWithTitle:#"Alert" message:#"Please try again!"];
}
[iPhoneXMPPAppDelegate stopIndicator];
[self.containerTbl reloadData];
}];
}
Output is in NSData Format:
4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAEcKADAAQAAAABAAAC9gAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs%2BEJ%2B/8AAEQgC9gRwAwERAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5%2Bv/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZ
First you need to change the Base64string to NSData and then you can easily convert to UIImage. Here are the steps:
(1) Convert Base64String to NSData using the NSData+Base64 files.
NSData *imageData = [NSData dataFromBase64String:originalString];
(2) Now you can convert the NSData to Image as follows:
UIImage *newImage = [UIImage imageWithData:imageData];

UIScrollView dynamic contents not appearing

I'm having a trouble dynamically adding UIButtons with background image as subviews to a UIScrollView. Its kind of a image gallery using UIButtons on a scrollView. I have used this method for couple of my apps, it works fine for me with the static contents.
But this time, Im loading images from a web service and saved to documents directory, then call the method to create the gallery. Logic is same with my other apps. But I cannot figure out what is the issue here.
I'll put here both the codes one is for retrieving data and other is the creating gallery.
Data retrieving from server
-(void)loadDataFromServer{
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
arrCats = [[NSMutableArray alloc]init];
arrPromos = [[NSMutableArray alloc]init];
//[spinMenu startAnimating];
// load promo images from the server
for(int i=0;i<[arrPromos count];i++)
{
NSString *urlString = [Constants getImages:[[arrPromos objectAtIndex:i] objectForKey:#"image"]];
NSLog(#"Get Images API Call : %#", urlString);
NSURL *imageurl = [NSURL URLWithString:urlString];
//get a dispatch queue
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//this will start the image loading in bg
dispatch_async(concurrentQueue, ^{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:imageurl];
//this will set the image when loading is finished
dispatch_async(dispatch_get_main_queue(), ^{
if(imageData != nil){
// save the images temporally
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsPath = [paths objectAtIndex:0]; //Get the docs directory
NSString *filePath = [documentsPath stringByAppendingPathComponent:[[arrPromos objectAtIndex:i] objectForKey:#"image"]]; //Add the file name
[imageData writeToFile:filePath atomically:YES];
}
});
});
}
// Load promotions from server
dispatch_async(queue, ^{
NSLog(#"Promotions Loading Started");
NSString *urlString = [Constants getAllPromotions:#"GetPromo.php"];
NSLog(#"Get Promotions API Call : %#", urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// Specify that it will be a GET request
request.HTTPMethod = #"GET";
[request setHTTPShouldHandleCookies:NO];
NSURLResponse *responseURL;
NSError *error;
NSData *dataPromotions = [NSURLConnection sendSynchronousRequest:request returningResponse:&responseURL error:&error];
if (responseURL == nil)
{
// Check for problems
if (error != nil)
{
NSLog(#"Get Promtions Connection failed! Error - %#", [error localizedDescription]);
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Connection Error!" message:#"Promotions data failed to load!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
}
}
else
{
NSString *responseString = nil;
responseString = [[NSString alloc] initWithData:dataPromotions encoding:NSUTF8StringEncoding];
if ([responseString rangeOfString:#"error"].location == NSNotFound)
{
NSDictionary *response = [[NSDictionary alloc] init];
response = (NSDictionary *)[responseString JSONValue];
NSLog(#"Response : Promotions %#", response);
if(response != Nil){
if([response count]>0){
arrPromos = [NSMutableArray arrayWithArray:[response objectForKey:#"Promos"]];
NSLog(#"ArrPromos # loading %#", arrPromos);
// create promos galley
[self createPromosGallery];
}
}
}
}
});
Note: [self createPromosGallery]; is calling after download all the images and data.
Create Gallery
-(void) createPromosGallery{
// sort arrPromos based on priority
for(int i=0; i<[arrPromos count];i++){
[arrPromos sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
NSDictionary *dict1 = obj1;
NSDictionary *dict2 = obj2;
NSString *string1;
NSString *string2;
if(![[dict1 objectForKey:#"priority"] isKindOfClass: [NSNull class]])
string1 = [dict1 objectForKey:#"priority"];
if(![[dict2 objectForKey:#"priority"] isKindOfClass: [NSNull class]])
string2 = [dict2 objectForKey:#"priority"];
return [string1 compare:string2 options:NSNumericSearch];
}];
}
NSLog(#"ArrPromos %#", arrPromos);
// scrollView size
CGFloat screenHieght = [UIScreen mainScreen].bounds.size.height;
if(screenHieght>500){
scrollView.frame = CGRectMake(0, 0, 320, 568);
}
else{
scrollView.frame = CGRectMake(0, 0, 320, 480);
}
// define scrollview height
int scrollHieght;
scrollHieght = ([arrPromos count]-1)/2;
NSLog(#"Scroll height %d",scrollHieght);
scrollView.contentSize = CGSizeMake(scrollView.frame.size.width , scrollHieght * 160 +200);
scrollView.pagingEnabled = NO;
scrollView.showsHorizontalScrollIndicator = NO;
scrollView.showsVerticalScrollIndicator = NO;
scrollView.scrollsToTop = NO;
scrollView.decelerationRate = UIScrollViewDecelerationRateFast;
scrollView.delegate = self;
for(int i=0;i<[arrPromos count];i++)
{
float x;
float y;
if(i%2==0)
{
x=30.0;
y=(i/2)*160+25;
}
if(i%2==1) {
x=170.0;
y=(i/2)*160+25;
}
// retreive saved images
NSString *strImgName;
UIImage *buttonUpImage;
// create buttons
button = [UIButton buttonWithType:UIButtonTypeCustom];
strImgName = [[arrPromos objectAtIndex:i] objectForKey:#"image"];
NSLog(#"Button image name %#", strImgName);
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
NSString *docDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#",docDirectory,strImgName];
buttonUpImage = [UIImage imageWithContentsOfFile:filePath];
[button setBackgroundImage:buttonUpImage forState:UIControlStateNormal];
button.frame = CGRectMake(x, y, 120,140);
[button setTag:i];
[button addTarget:self action:#selector(promoBtnPressed:)forControlEvents:UIControlEventTouchUpInside];
[self.scrollView addSubview:button];
}
}
Note: I tested on both iOS 7 and 6. In iOS 7, it takes very long time to appear images on scrollView(Currently have only 2 images). Or else, If I TAP on scroolView then the images appear.
In ios 6, nothing appear
//Make a method that has url (fileName) Param
NSArray *documentsDirectory =
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSFileManager *fileManager =[NSFileManager defaultManager];
if ([fileManager fileExistsAtPath:textPath])
{
return YES;
}
else
{
return NO;
}
UIImageView *imgView = [[UIImageView alloc] initWithImage:[UIImage
imageNamed:#""]];//Placeholder image
if ([url isKindOfClass:[NSString class]])
{
imgView.image = [UIImage imageNamed:[url absoluteString]];
imgView.contentMode = UIViewContentModeScaleAspectFit;
}
else if ([fileManager fileExistsAtPath:url])
{
NSString *textPath = [documentsDirectory stringByAppendingPathComponent:url];
NSError *error = nil;
NSData *fileData = [NSData dataWithContentsOfFile:textPath options:NSDataReadingMappedIfSafe error:&error];
if (error != nil)
{
DLog(#"There was an error: %#", [error description]);
imgView.image=nil;
}
else
{
imgView.image= [UIImage imageWithData:fileData]
}
}
else
{ UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]
initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGPoint center = imgView.center;
// center.x = imgView.bounds.size.width / 2;
spinner.center = center;
[spinner startAnimating];
[imgView addSubview:spinner];
dispatch_queue_t downloadQueue = dispatch_queue_create("iamge downloader", NULL);
dispatch_async(downloadQueue, ^{
NSData *imgData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
[spinner removeFromSuperview];
UIImage *image = [UIImage imageWithData:imgData];
NSError *error = nil;
[imgData writeToFile:url options:NSDataWritingFileProtectionNone error:&error];
if (error != nil)
}
else
{
}
imgView.image = image;
});
});
}
Thats UIImageView loading an image if it doesnot exist in document then it Save it , An Activity indicator is added to show image is loading to save,
Yes it is because you are downloading and then saving the images which takes time. I suggest you to use any library for downloading images and saving them.
Ex : SDWebImage

Resources