iOS table view lag issue, i'm using dispatch and save cache - ios

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"TableViewCell" forIndexPath:indexPath];
cell.tag = indexPath.row;
//cell.imageView.image = nil;
// Rounded Rect for cell image
CALayer *cellImageLayer = cell.imageView.layer;
[cellImageLayer setCornerRadius:25];
[cellImageLayer setMasksToBounds:YES];
[self getImages];
[self storeImages];
UIImage *image =_ResimSonHali[indexPath.row];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(queue, ^(void) {
if (image) {
dispatch_async(dispatch_get_main_queue(), ^{
if (cell.tag == indexPath.row) {
CGSize itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContext(itemSize);
CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
[image drawInRect:imageRect];
// cell.ThumbImage.image = image1;
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[cell setNeedsLayout];
}
});
}
});
cell.TitleLabel.text = _TarifAdi[indexPath.row];
return cell;
}
-(void)getImages
{
NSMutableArray *fuckingArrayYemek = [[NSMutableArray alloc] init];
for (int i=0; i<[_ResimAdiBase count]; i++)
{
NSString *testString=_ResimAdiBase[i];
NSArray *ImageNames = [testString componentsSeparatedByString:#"."];
[self cacheImage: _ResimAdi[i] : ImageNames[0] ];
[fuckingArrayYemek addObject:ImageNames[0]];
}
_ResimSonAdi = fuckingArrayYemek;
}
-(void) storeImages
{
NSMutableArray *fuckingArrayYemekName = [[NSMutableArray alloc] init];
for (int i=0; i<[_ResimAdiBase count]; i++)
{
[fuckingArrayYemekName addObject:[self getCachedImage:_ResimSonAdi[i]]];
}
_ResimSonHali = fuckingArrayYemekName;
}
- (void) cacheImage: (NSString *) ImageURLString : (NSString *)imageName
{
NSURL *ImageURL = [NSURL URLWithString: ImageURLString];
// Generate a unique path to a resource representing the image you want
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex: 0];
NSString *docFile = [docDir stringByAppendingPathComponent: imageName];
// Check for file existence
if(![[NSFileManager defaultManager] fileExistsAtPath: docFile])
{
// 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];
// 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: docFile atomically: YES];
}
else if([ImageURLString rangeOfString: #".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound ||
[ImageURLString rangeOfString: #".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound)
{
[UIImageJPEGRepresentation(image, 100) writeToFile: docFile atomically: YES];
}
}
}
- (UIImage *) getCachedImage : (NSString *)imageName
{
NSArray *paths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString* cachedPath = [documentsDirectory stringByAppendingPathComponent:imageName];
UIImage *image;
// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: cachedPath])
{
image = [UIImage imageWithContentsOfFile: cachedPath]; // this is the cached image
}
else
{
NSLog(#"Error getting image %#", imageName);
}
return image;
}
When i load 20 data, our table do not lagging but when our try to increase data size table view getting lag how we can prove this problem. First we tried dispatch then we tried save images cache still we got lag. Approximately, we deal with this problem about 3 days.

This is the problem line inside cacheImage() method, which is called with every call of "cellForRowAtIndexPath" method
NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL];
So to resolve the problem use this line under dispatch_async section. And update your code according to it.

Related

How to load images from documents directory into image view in Objective-C

NSString *path = [NSString stringWithFormat:#"%#/%#",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0], parentFolderName] ;
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:nil];
NSEnumerator *enumerator = [dirContents objectEnumerator] ;
id fileName ;
NSMutableArray *fileArray = [[NSMutableArray alloc] init] ;
while (fileName = [enumerator nextObject])
{
NSString *fullFilePath = [path stringByAppendingPathComponent:fileName];
NSRange textRangeJpg = [[fileName lowercaseString] rangeOfString:[#".png" lowercaseString]];
if (textRangeJpg.location != NSNotFound)
{
originalImage = [UIImage imageWithContentsOfFile:fullFilePath];
[fileArray addObject:originalImage];
}
}
You should try this code to save and retrieve image from the document directory:
I have implemented these methods in AppDelegate.m
-(NSString *)getDocumentDirectoryPath:(NSString *)Name
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *savedImagePath = [documentsDirectory stringByAppendingPathComponent:Name];
NSLog(#"savedImagePath: %#", savedImagePath);
return savedImagePath;
}
-(BOOL)saveImage:(UIImage *)image withName:(NSString *)Name
{
NSData *imageData = UIImagePNGRepresentation(image);
BOOL success = [imageData writeToFile:[AppDelegate getDocumentDirectoryPath:Name] atomically:NO];
return success;
}
-(UIImage *)getRealtorImage:(NSString *)Name
{
UIImage *img = [UIImage imageWithContentsOfFile:[AppDelegate getDocumentDirectoryPath:Name]];
return img;
}
#Sandy Please try the following code
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(100,100,200,200)];
NSData *imgData = [[NSData alloc] initWithContentsOfURL:[NSURL fileURLWithPath:imageFilePath]];
if (imgData != nil)
{
UIImage *thumbNail = [[UIImage alloc] initWithData:imgData];
imageView.image = thumbNail;
}
[self.view addSubView:imageView];

in UITableView first entry and last entry switching record data when loading from server

I am developing an app that will display data from server in a parallax type UITableView, and here is my code. Everything is loading great, but cell data(image, etc) keep switching from one cell to another.
- (void)viewDidLoad
{
[self hasInternet];
self.tableView.dataSource = self;
self.tableView.delegate = self;
[self loadData];
self.edgesForExtendedLayout=UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars=NO;
self.automaticallyAdjustsScrollViewInsets=NO;
[super viewDidLoad];
}
- (void)viewWillAppear:(BOOL)animated
{
[self scrollViewDidScroll:nil];
[super viewWillAppear:animated];
[self loadData];
self.tableView.dataSource = self;
self.tableView.delegate = self;
}
- (void) loadData{
name = #"name";
email = #"email";
thumbnail = #"thumbnail";
myObject = [[NSMutableArray alloc] init];
NSData *jsonSource = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://URL.php"]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonSource options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dataDict in jsonObjects) {
NSString *title_data = [dataDict objectForKey:#"fname"];
NSString *title_data2 = [dataDict objectForKey:#"lname"];
NSString *fulname = [NSString stringWithFormat:#"%# %#", title_data, title_data2];
NSString *emAil = [dataDict objectForKey:#"email"];
NSString *thumbnail_data = [dataDict objectForKey:#"img"];
thumbnail_data = [NSString stringWithFormat:#"http://URL/upload/%#",thumbnail_data];
dictionary = [NSDictionary dictionaryWithObjectsAndKeys: fulname, name, emAil, email, thumbnail_data, thumbnail, nil];
[myObject addObject:dictionary];
}
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return myObject.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"parallaxCell";
JBParallaxCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell=[[JBParallaxCell alloc]initWithStyle:
UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];
NSMutableString *text;
text = [NSMutableString stringWithFormat:#"%#",[tmpDict objectForKeyedSubscript:name]];
NSMutableString *mail;
mail = [NSMutableString stringWithFormat:#"%#",[tmpDict objectForKeyedSubscript:email]];
NSMutableString *images;
images = [NSMutableString stringWithFormat:#"%# ",[tmpDict objectForKey:thumbnail]];
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:[tmpDict objectForKey:thumbnail]];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
cell.parallaxImage.image = [[UIImage alloc]initWithData:data];
});
});
cell.titleLabel.text = [NSString stringWithFormat:#"%#",text];
cell.subtitleLabel.text = [NSString stringWithFormat:#"%#",mail];
return cell;
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
NSArray *visibleCells = [self.tableView visibleCells];
for (JBParallaxCell *cell in visibleCells) {
[cell cellOnTableView:self.tableView didScrollOnView:self.view];
}
}
When I compile it, it shows all my data but then keep switching from one cell to another. Any help will be appreciated. Thanks
Because UITableView reuse the cell so when you scroll down or up the previous cell which is gone from your tableview bound is reuse. but it's image view has an image when it use last time so you have to clear first the imageview.
so put this line
cell.parallaxImage.image = nil;
Before the dispatch queue
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can use this code it will save the images in document directry and then show it.
please change the variable name.
NSString *imageURL = [[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"];
NSURL *url = [NSURL URLWithString:imageURL];
NSArray *seperate = [[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"] componentsSeparatedByString:#"/"];
NSString *fileName = [NSString stringWithFormat:#"%#.png",[seperate objectAtIndex:seperate.count-1]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/MyFolder"];
NSError *error;
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
NSString *getImagePath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];
UIImage *img = [UIImage imageWithContentsOfFile:getImagePath];
if ([img isKindOfClass:[UIImage class]]) {
//Set Downloaded Image
[cell.matchUserImageView setImage:img];
}
else {
if ([[ValidationString sharedManager] isNullString:[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"]] == YES) {
//Set Default Image
[cell.matchUserImageView setImage:[UIImage imageNamed:#"photo_icon.png"]];
}
else{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSData *imageData = [NSData dataWithContentsOfURL:url];
NSArray *seperate = [[[matcheListArr objectAtIndex:indexPath.row] valueForKey:#"thumbnail_image"] componentsSeparatedByString:#"/"];
NSString *fileName = [NSString stringWithFormat:#"%#.png",[seperate objectAtIndex:seperate.count-1]];
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
[cell.matchUserImageView setImage:[UIImage imageWithData:imageData]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/MyFolder"];
NSString *savedImagePath = [dataPath stringByAppendingPathComponent:[NSString stringWithFormat:#"%#",fileName]];
[imageData writeToFile:savedImagePath atomically:NO];
});
});
}
}

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

Store images in application

I've created folder called "Image store" using the following code. my requirment is i want to save images to the folder "Image store" on api success and the images should be saved in application itself not in database or photo album.I want to know the mechanism by which i can store images in application
-(void) createFolder {
UIImage *image = [[UIImage alloc]init];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error];
else
{
}
}
//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,
u can do something like this
u can run a loop for images like this
//at this point u can get image data
for(int k = 0 ; k < imageCount; k++)
{
[self savePic:[NSString stringWithFormat:#"picName%d",k] withData:imageData];//hear data for each pic u can send
}
- (void)savePic:(NSString *)picName withData:(NSData *)imageData
{
if(imageData != nil)
{
NSString *path = [NSString stringWithFormat:#"/ImageStore/%#.png",pincName];
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,path]; //path means ur destination contain's this format -> "/foldername/picname" pickname must be unique
if(![[NSFileManager defaultManager] fileExistsAtPath:[pngPath stringByDeletingLastPathComponent]])
{
NSError *error;
[[NSFileManager defaultManager] createDirectoryAtPath:[pngPath stringByDeletingLastPathComponent] withIntermediateDirectories:YES attributes:nil error:&error];
if(error)
{
NSLog(#"error in creating dir");
}
}
[imageData writeToFile:pngPath atomically:YES];
}
}
after successful download and saving u can retrieve images like below
- (UIImage *)checkForImageIn:(NSString *)InDestination
{
NSString *Dir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *pngPath = [NSString stringWithFormat:#"%#%#",Dir,InDestination];//hear "InDestination" format is like this "/yourFolderName/imagename" as i said imagename must be unique .. :)
UIImage *image = [UIImage imageWithContentsOfFile:pngPath];
if(image)
{
return image;
}
else
return nil;
}
link to find path
see this link to find the path ..
aganin do same this run loop like below
NSMutableArray *imagesArray = [[NSMutableArray alloc]init];
for(int k = 0 ; k < imageCount; k++)
{
UIImage *image = [self checkForImageIn:[NSString stringWithFormat: #"/yourFolderName/ImageName%d",k]];//get the image
[imagesArray addObject:image];//store to use it somewhere ..
}
Write this code after creating directory
NSString *path= [documentsDirectory stringByAppendingPathComponent:#"/ImageStore"];
UIImage *rainyImage =[UImage imageNamed:#"rainy.jpg"];
NSData *Data= UIImageJPEGRepresentation(rainyImage,0.0);
[data writeToFile:path atomically:YES]
The document directory is found like this:
// Let's save the file into Document folder.
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// If you go to the folder below, you will find those pictures
NSLog(#"%#",docDir);
NSLog(#"saving png");
NSString *pngFilePath = [NSString stringWithFormat:#"%#/test.png",docDir];
Thats just a sample of the code provided which tells you where the correct path is to save in your ipone device.
Check the below blog post,it's step by step guide with source code .
Download an Image and Save it as PNG or JPEG in iPhone SDK

Error when recalling directory to Collection View

I am using this code to recall the directory that I have made for each genre. However I get errors saying at the images part at the [arrayCollectionImages addObject:image]; Can you explain what is wrong with the last piece of code. I also have an warning at arrayCollectionImages saying local declaration of arrayColectionImages hide instance variable. It is also telling me that the [[cell collectionImageView]setImage:[UIImage imageNamed:[arrayCollectionImages objectAtindex:indexPath.item]]]; No visible #interface for "NSArray" declares the selector "objectAtindex:;" What did I have done wrong?
#import "CollectionViewController.h"
#import "CollectionCell.h"
#interface CollectionViewController (){
NSArray *arrayCollectionImages;
}
#end
#implementation CollectionViewController
- (void)viewDidLoad {
NSArray *allImagesArray = [[NSArray alloc ]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *location=#"Genre1";
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:location];
NSArray *directoryContent = [[NSFileManager defaultManager] directoryContentsAtPath: fPath];
for(NSString *str in directoryContent){
NSString *finalFilePath = [fPath stringByAppendingPathComponent:str];
NSData *data = [NSData dataWithContentsOfFile:finalFilePath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[allImagesArray addObject:image];
}
}
[super viewDidLoad];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"ReuseID" forIndexPath:indexPath];
[[cell collectionImageView]setImage:[UIImage imageNamed:[arrayCollectionImages objectAtIndex:indexPath.item]]];
return cell;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [arrayCollectionImages count];
}
#end
This is my code for saving to directory
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
FrontCamera = NO;
cameraSwitch.selectedSegmentIndex = 1;
captureImage.hidden = YES;
[pickerViewContainer addSubview:SaveTopicker];
arraygenre = [[NSMutableArray alloc] init];
[arraygenre addObject:#"Tops"];
[arraygenre addObject:#"Pants"];
[arraygenre addObject:#"Coats"];
[arraygenre addObject:#"Shoes"];
[arraygenre addObject:#"Hats"];
[arraygenre addObject:#"Others"];
pickerViewContainer.frame = CGRectMake(0, 800, 320, 261);
}
- (void)viewDidAppear:(BOOL)animated {
[self initializeCamera];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
//fetch Category Name from the array used to fill the Picker View
NSString *categoryName= [arraygenre objectAtIndex:row];
NSString *fPath = [documentsDirectory stringByAppendingPathComponent:categoryName];
NSFileManager *fileManager=[[NSFileManager alloc]init];
[fileManager createDirectoryAtPath:fPath withIntermediateDirectories:YES attributes:nil error:nil];
UIImage *image = captureImage.image;
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:fPath atomically:YES];
}
The method name is objectAtIndex:. You have the "i" in the method name in lower case which is incorrect.

Resources