I want to download multiple images from URL to my device in iOS App.
//
// ImageDownload.m
//
#import "ImageDownload.h"
#implementation ImageDownload {
int *position;
NSArray *downloableImages;
}
- (void)start:(NSArray *)images delegate:(id)delegate
{
position = 0;
downloableImages = images;
NSUInteger *count = ((NSUInteger *)[downloableImages count]);
NSLog(#"%d", count);
[self startDownload];
}
- (void)startDownload
{
NSUInteger *imageDataCount;
NSArray *image;
NSString *filename;
NSString *fileurl;
NSURLRequest *imageUrlRequest;
image = [downloableImages objectAtIndex:position];
NSLog(#"%d", position);
NSArray *imageData = [image valueForKey:#"image"];
imageDataCount = ((NSUInteger *)[imageData count]);
if (imageDataCount > 0) {
filename = [imageData objectAtIndex:0];
fileurl = [imageData objectAtIndex:1];
NSLog(#"%#", fileurl);
imageUrlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:fileurl]];
NSURLConnection *imageUrlConnection = [[NSURLConnection alloc] initWithRequest:imageUrlRequest delegate:self startImmediately:TRUE];
} else {
NSUInteger *count = ((NSUInteger *)[downloableImages count]);
if (((NSUInteger *)position) < ((NSUInteger *)count - 1)) {
position = position + 1;
[self startDownload];
}
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"finish image...");
NSUInteger *count = ((NSUInteger *)[downloableImages count]);
if (((NSUInteger *)position) < ((NSUInteger *)count - 1)) {
position = position + 1;
[self startDownload];
}
}
#end
For now... I only check the position of the download and current URL,
Exists 27 files to download... but the download not go one by one... check this output:
Position: 0
http.....fichero00.jpg
Finish download
Position: 4
http.....fichero04.jpg
Finish download
Position: 8
http.....fichero08.jpg
Finish download
Create an ivar NSOperationQueue *operationQueue; in your .h file and init it in your .m file:
operationQueue = [[NSOperationQueue alloc] init];
operationQueue.maxConcurrentOperationCount = 1;
For downloading images, create a method that takes an image URL and call it for each image:
-(void)downloadImageAtURL:(NSURL *)imageURL {
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:imageURL] queue:operationQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// Do something with your images here...
};
}
You can try this code.. Its 100 % Working for me
You can get more reference here
-(IBAction)startdownload
{
for (int i=0; i<[downloadarray count]; i++) //download array have url links
{
NSURL *URL = [NSURL URLWithString:[downloadarray objectAtIndex:i]];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]initWithURL:URL];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if([data length] > 0 && [[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"])
{
//make your image here from data.
UIImage *imag = [[UIImage alloc] initWithData:[NSData dataWithData:data]];
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [array objectAtIndex:0];
NSString *imgstr=[NSString stringWithFormat:#"%d",i];
NSString *pngfilepath = [NSString stringWithFormat:#"%#sample%#.png",docDir,imgstr];
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(imag)];
[data1 writeToFile:pngfilepath atomically:YES];
}
else if ([data length] == 0 && [[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"])
{
NSLog(#"No Data!");
}
else if (![[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"]){
NSLog(#"Error = %#", error);
}
}];
}
-(IBAction)viewfile
{
NSMutableArray *arr=[[NSMutableArray alloc]init];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pngfilepath = [NSString stringWithFormat:#"%#",documentsDirectory];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:pngfilepath error:&error];
for (int i=0; i<[filePathsArray count]; i++){
NSString *pngfilepath = [NSString stringWithFormat:#"%#%#",documentsDirectory, [filePathsArray objectAtIndex:i]];
[arr addObject:[UIImage imageWithContentsOfFile:pngfilepath]];
}
myimageview = [[UIImageView alloc] initWithImage:[arr objectAtIndex:0]]; //Here myimageview is UIImageView
}
Hope This Helps!!!
Work around NSOperationQueue it allow you to control how much operation are run concurrently.
Create:
NSOperationQueue *queue = [NSOperationQueue new];
queue.maxConcurrentOperationCount = 1;
Then add operations :
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
... here is you code with converting image to data and addition it to NSURLConnection
}];
[operation setCompletionBlock:^{
....something that you want to do, after operation completes
}];
[queue addOperation:operation];
More about NSOperation:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/occ/cl/NSOperation
Here is my new code...
I have a delay when I try to update a UIProgressView
//
// ImageDownload.m
//
#import "ImageDownload.h"
#implementation ImageDownload {
NSMutableArray *downloableImages;
int position;
Sync *mySync;
}
- (void)start:(NSArray *)images sync:(Sync *)sync
{
NSArray *imageData;
int imageDataCount;
mySync = sync;
downloableImages = [[NSMutableArray alloc] init];
for (NSArray *image in images) {
imageData = [image valueForKey:#"image"];
imageDataCount = [imageData count];
if (imageDataCount > 0) {
[downloableImages addObject:imageData];
}
}
[self downloadAllFiles];
}
- (void)downloadAllFiles
{
NSString *filename;
NSString *fileUrl;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = [paths objectAtIndex:0];
position = 0;
int count = [downloableImages count];
NSLog(#"%#", downloableImages);
NSLog(#"total files %d", count);
for (NSArray *image in downloableImages) {
filename = [image objectAtIndex:0];
fileUrl = [image objectAtIndex:1];
NSURL *url = [NSURL URLWithString:fileUrl];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
position++;
float progress = (float)position / (float)count;
//update UIProgressView
[mySync setProgressImageDownload:progress];
if ([data length] > 0 && [[NSString stringWithFormat:#"%#", error] isEqualToString:#"(null)"]) {
UIImage *downloadedImage = [[UIImage alloc] initWithData:[NSData dataWithData:data]];
NSString *imageDestinationPath = [NSString stringWithFormat:#"%#%#", cacheDirectory, filename];
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(downloadedImage, 100.0)];
[imageData writeToFile:imageDestinationPath atomically:YES];
}
if (position == count) {
NSLog(#"all complete...");
[mySync downloadImagesComplete];
}
}];
}
}
#end
Related
Hi I am getting single image from server using url in iOS.
my code is like this
- (IBAction)overlaysClicked:(id)sender
{
NSLog(#"overlays Clicked");
request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://sukhada.co.in/img/overlays/neon/ov1.png"]];
[NSURLConnection connectionWithRequest:request delegate:self];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:#"image.jpg"];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://sukhada.co.in/img/overlays/neon/ov1.png"]];
[thedata writeToFile:localFilePath atomically:YES];
UIImage *img = [[UIImage alloc] initWithData:thedata];
self.overlayImgView.image=img;
}
To get multiple images from server my code like this
NSURL *myUrl = [NSURL URLWithString:#"http://sukhada.co.in/img/overlays/neon.zip"];
NSURLRequest *myRequest = [NSURLRequest requestWithURL:myUrl cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
myData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection *myConnection = [[NSURLConnection alloc] initWithRequest:myRequest delegate:self startImmediately:YES];
//my Array is like this in viewDidload
self.overlaysImgsArray = [[NSMutableArray alloc]initWithContentsOfURL:[NSURL URLWithString:#"http://sukhada.co.in/img/overlays/neon.zip"]];
NSLog(#"urls is %#",overlaysImgsArray);
for (int i=0; i<[overlaysImgsArray count]; i++)
//download array have url links
{
NSURL *URL = [NSURL URLWithString:[overlaysImgsArray objectAtIndex:i]];
NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc]initWithURL:URL];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if([data length] > 0 && [[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"])
{
//make your image here from data.
UIImage *imag = [[UIImage alloc] initWithData:[NSData dataWithData:data]];
NSArray *array = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [array objectAtIndex:0];
NSString *imgstr=[NSString stringWithFormat:#"%d",i];
NSString *pngfilepath = [NSString stringWithFormat:#"%#sample%#.png",docDir,imgstr];
NSData *data1 = [NSData dataWithData:UIImagePNGRepresentation(imag)];
[data1 writeToFile:pngfilepath atomically:YES];
}
else if ([data length] == 0 && [[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"])
{
NSLog(#"No Data!");
}
else if (![[NSString stringWithFormat:#"%#",error] isEqualToString:#"(null)"]){
NSLog(#"Error = %#", error);
}
}];
}
}
But this is not working for me please anybody suggest me how to get multiple images from server using one url which contains all the images. Please anybody
thank you in advance
In your case you can try like this
first you need to save all the 10 image in directory and the fetch one by one as your requirement .this code save all image from your url
try this
- (IBAction)overlaysClicked:(id)sender {
//Note all your image saved with ov1.png,ov2.png......& so .
for (int i=1; i<=10; i++) {
NSString *st2=#"ov";
NSString *st1=#"http://sukhada.co.in/img/overlays/neon/ov";
NSString *imageN=[st2 stringByAppendingString:[NSString stringWithFormat:#"%d",i]];
NSString *imgNameforkey=[imageN stringByAppendingString:#".png"];
NSString *url=[st1 stringByAppendingString:[NSString stringWithFormat:#"%d",i]];
NSString *imgname=[url stringByAppendingString:#".png"];
NSLog(#" all=%#",imgname);
NSLog(#"overlays Clicked");
request = [NSURLRequest requestWithURL:[NSURL URLWithString:imgname]];
[NSURLConnection connectionWithRequest:request delegate:self];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *localFilePath = [documentsDirectory stringByAppendingPathComponent:imgname];
NSData *thedata = [NSData dataWithContentsOfURL:[NSURL URLWithString:imgname]];
[thedata writeToFile:localFilePath atomically:YES];
UIImage *img = [[UIImage alloc] initWithData:thedata];
NSLog(#"imgs %#",img);
// self.overlayImgView.image=img;
}
}
here you can see all image saved
fetch the image
using loop or with name
NSArray *directoryPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES);
NSString *imagePath = [directoryPath objectAtIndex:0];
imagePath= [imagePath stringByAppendingPathComponent:#"ov1.png"];
NSData *data = [NSData dataWithContentsOfFile:imagePath];
UIImage *img = = [UIImage imageWithData:data];
download a zip file from url and save it .use this code inside the button action. no need for loop now. try this
- (IBAction)overlaysClicked:(id)sender {
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_async(queue, ^{
NSLog(#"Beginning download");
NSString *stringURL = #"http://sukhada.co.in/img/overlays/neonra.zip";
NSURL *url = [NSURL URLWithString:stringURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
//Find a cache directory. You could consider using documenets dir instead (depends on the data you are fetching)
NSLog(#"Got the data!");
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
//Save the data
NSLog(#"Saving");
NSString *dataPath = [path stringByAppendingPathComponent:#"img.zip"];
dataPath = [dataPath stringByStandardizingPath];
[urlData writeToFile:dataPath atomically:YES];
});
}
and check you will get img.zip file
I am making an app where I must download some files from a webserver and save it locally. I have the following JSON:
{
status: 200,
message: "OK",
files: [
"magazines/dentalasia/DentalAsia1/images/toc-thumb-dummy.jpg",
"magazines/dentalasia/DentalAsia1/images/bg-grid-iphone.png",
"magazines/dentalasia/DentalAsia1/images/cover/toc-thumb.jpg",
"magazines/dentalasia/DentalAsia1/images/cover/cover-typo.png",
...
]
}
What I do is I save this string values into an NSArray and then I'm going to download each one of them.
-(IBAction)downloadMagazine:(id)sender{
// 1
progressView.hidden = NO;
NSArray *splitArray = [mag.mag_folder componentsSeparatedByString:#"/"];
NSString *magName = [splitArray lastObject];
NSString *string = [NSString stringWithFormat:#"%#/webservice/magazine/get-book/apikey/%#/magazine/%#/name/%#",baseUrl,apikey,magazine,magName];
NSLog(#"STRING IS %#",string);
NSURL *url = [NSURL URLWithString:string];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 2
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
//Create general directory
NSDictionary *JSON = [responseObject copy];
NSArray *files = [JSON valueForKey:#"files"];
reversedFiles = [[files reverseObjectEnumerator] allObjects];
amountFiles = reversedFiles.count;
NSArray *splitArray = [mag.mag_folder componentsSeparatedByString:#"/"];
NSString *magName = [splitArray lastObject];
NSString *rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
NSError *error = nil;
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
for(int i = 0 ; i<reversedFiles.count ; i++){
NSString *file = [reversedFiles objectAtIndex:i];
NSString *strUrl = [NSString stringWithFormat:#"%#/%#",baseUrl,file];
NSArray *splitUrl = [file componentsSeparatedByString:#"/"];
NSString *lastObject = [splitUrl lastObject];
if ([lastObject rangeOfString:#"."].location == NSNotFound) {
rootString = nil;
rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
for (int i=0; i<splitUrl.count; i++) {
if(i>2){
NSString *pathComponent = [NSString stringWithFormat:#"/%#",[splitUrl objectAtIndex:i]];
rootString = [rootString stringByAppendingPathComponent:pathComponent];
}
}
if (![[NSFileManager defaultManager] fileExistsAtPath:rootString])
[self calculatePie:i];
[[NSFileManager defaultManager] createDirectoryAtPath:rootString withIntermediateDirectories:NO attributes:nil error:&error];
}else{
NSURL *url = [NSURL URLWithString:strUrl];
NSData *data = [NSData dataWithContentsOfURL:url];
if(data)
{
rootString = nil;
rootString = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0]stringByAppendingPathComponent:magName];
rootString = [rootString stringByAppendingPathComponent:#"/www"];
for (int i=0; i<splitUrl.count; i++) {
if(i>2){
NSString *pathComponent = [NSString stringWithFormat:#"/%#",[splitUrl objectAtIndex:i]];
rootString = [rootString stringByAppendingPathComponent:pathComponent];
}
}
[data writeToFile:rootString atomically:YES];
[self calculatePie:i];
}
}
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// 4
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving magazine"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
// 5
[operation start];
}
-(void)calculatePie:(int)i{
float progress = (100.0 / amountFiles) * i;
float progress2 = progress / 100.0;
NSLog(#"Progress is %f",progress2);
[progressView setProgress:progress2 animated:YES];
}
And this is how a part of my LOG looks like:
2014-04-24 08:56:18.507 DentalAsia[47301:60b] Progress is 0.340136
2014-04-24 08:56:18.764 DentalAsia[47301:60b] Progress is 0.343537
2014-04-24 08:56:19.041 DentalAsia[47301:60b] Progress is 0.346939
2014-04-24 08:56:19.210 DentalAsia[47301:60b] Progress is 0.350340
2014-04-24 08:56:19.549 DentalAsia[47301:60b] Progress is 0.353741
2014-04-24 08:56:19.714 DentalAsia[47301:60b] Progress is 0.357143
But for some reason my UIProgressview is not moving!
Can someone help me with this ?
Thanks !
Make sure you update the progress view on the main thread:
-(void)calculatePie:(int)i{
float progress = (100.0 / amountFiles) * i;
float progress2 = progress / 100.0;
NSLog(#"Progress is %f",progress2);
dispatch_async(dispatch_get_main_queue(), ^{
[progressView setProgress:progress2 animated:YES];
});
}
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
I want to retrieve a folder containing 10 images from server, then store that folder in my document directory. I did some code, but when I run it, I am getting the image urls, not the images themselves. Can anyone help me out?
My code:
-(void)viewWillAppear:(BOOL)animated
{
NSMutableData *receivingData = [[NSMutableData alloc] init];
NSURL *url = [NSURL URLWithString:#"http://Someurl.filesCount.php"];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[receivingData appendData:data];
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error = nil;
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
printf("\n the path is :%s",[path UTF8String]);
NSString *zipPath = [path stringByAppendingPathComponent:#"filesCount.php"];
[receivingData writeToFile:zipPath options:0 error:&error];
NSString *documentsDirectoryPath = [[NSHomeDirectory() stringByAppendingPathComponent:#"Documents"] stringByAppendingPathComponent:#"filesCount"];
NSLog(#"the path %#",documentsDirectoryPath);
}
I made this function in my previous project. You need to pass your imageView and serverUrl, then its automatically show image in your imageView and save image to temp directory, when you want again to fetch same image, then next time it take image from disk.
+(void)downloadingServerImageFromUrl:(UIImageView*)imgView AndUrl:(NSString*)strUrl{
NSFileManager *fileManager =[NSFileManager defaultManager];
NSString* theFileName = [NSString stringWithFormat:#"%#.png",[[strUrl lastPathComponent] stringByDeletingPathExtension]];
NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"tmp/%#",theFileName]];
imgView.backgroundColor = [UIColor darkGrayColor];
UIActivityIndicatorView *actView = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
[imgView addSubview:actView];
[actView startAnimating];
CGSize boundsSize = imgView.bounds.size;
CGRect frameToCenter = actView.frame;
// center horizontally
if (frameToCenter.size.width < boundsSize.width)
frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
else
frameToCenter.origin.x = 0;
// center vertically
if (frameToCenter.size.height < boundsSize.height)
frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
else
frameToCenter.origin.y = 0;
actView.frame = frameToCenter;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSData *dataFromFile = nil;
NSData *dataFromUrl = nil;
dataFromFile = [fileManager contentsAtPath:fileName];
if(dataFromFile==nil){
dataFromUrl=[[[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]] autorelease];
}
dispatch_sync(dispatch_get_main_queue(), ^{
if(dataFromFile!=nil){
imgView.image = [UIImage imageWithData:dataFromFile];
}else if(dataFromUrl!=nil){
imgView.image = [UIImage imageWithData:dataFromUrl];
// NSString *fileName = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"tmp/%#",theFileName]];
BOOL filecreationSuccess = [fileManager createFileAtPath:fileName contents:dataFromUrl attributes:nil];
if(filecreationSuccess == NO){
NSLog(#"Failed to create the html file");
}
}else{
imgView.image = [UIImage imageNamed:#"NO_Image.png"];
imgView.tag = 105;
}
[actView removeFromSuperview];
[actView release];
});
});
}
Try using this code.
NSURL* url = [NSURL URLWithString:#"http://imageAddress.com"];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse * response,
NSData * data,
NSError * error) {
if (!error){
// do whatever you want with directory or store images.
NSImage* image = [[NSImage alloc] initWithData:data];
}
}];
Use this code to download the image using URL and store in document directory. Iterate the logic for set of images to download and store.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *imageURL = #"http://sampleUrl";
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
NSString *imagePath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"Image1.png"]];
if(image != NULL)
{
//Store the image in Document
NSData *imageData = UIImagePNGRepresentation(image);
[imageData writeToFile: imagePath atomically:YES];
}
If you'll showing the images loaded from server on UI, then
try SDWebImageView, can be used with UIButton or UIImageView, very easy and efficient.
example,
[yourImageView setImageWithURL:[NSURL URLWithString:#"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:#"placeholder.png"]];
Read how to use it?
Okay, now for multiple images, you may need to run a loop, if you've a common base url for all your pictures (on server) something like http://yoururl/server/pictures/1.png will be replace by 2.png 3.png ... n.png, or you get different urls for pictures need to pass that url, you can load it into imageview objects, and later save them into document directory (remember, SDWebImageView by default doing this work for you). You can turn this off too.
P.S. It will load images once and stored into local (in cache) it self, next time when you pass the same image url, it won't load from server and directly load the image from local.
I am uploading more than 100 images on server using following code and i Received memory warning after uploading few images. Please help me..
Here is my code for uploading image on sever :
-(void)uploadSingleFile
{
if(!self.objWebServices.bSyncWasOn)
{
NSLog(#"STOP upload Single File RETURN");
[self Call_SaveSyncedImageID];
return;
}
SyncItem* item = [arrSelSyncItemIDS objectAtIndex:nSyncItemIndex];
if(item.nType == SYNC_STATUS_NOT_SELECTED || item.nType == SYNC_STATUS_SYNC_DONE)
{
nSyncItemIndex = nSyncItemIndex + 1;
if([arrSelSyncItemIDS count] > nSyncItemIndex)
{
NSLog(#"Called uploadSingleFile");
[self uploadSingleFile];
return;
}
else
{
//[self LoadImages:!bShowHideSyncImages];
[SVProgressHUD dismiss];
[BtnStopSync setTitle:#"Start sync" forState:UIControlStateNormal];
self.objWebServices.bSyncWasOn = NO;
self.objWebServices.isFileUpload = NO;
if( [[NSUserDefaults standardUserDefaults] boolForKey:#"Notification_State"] ) // Setting Switch Bool
{
UIAlertView *Alert = [[UIAlertView alloc] initWithTitle:#"test" message:#"*** Sync completed successfully." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[Alert show];
}
}
}
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *srtprefSessionId = [NSString stringWithFormat:#"%#",[prefs objectForKey:#"prefSessionId"]];
BOOL isTrash = FALSE;
NSString *StrPath = #"/Pictures/"; //Change
ALAsset* temp = item.itemAsset;
NSDate* assetDate = (NSDate*)[temp valueForProperty:#"ALAssetPropertyDate"];
NSString* strID = #"";
strID = [[temp valueForProperty:#"ALAssetPropertyURLs"] description];
strID = [strID stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSString* strImageType = #"";
if ([strID rangeOfString:#"jpg"].location != NSNotFound || [strID rangeOfString:#"JPG"].location != NSNotFound ){
strImageType = #"jpg";
}
else if ([strID rangeOfString:#"png"].location != NSNotFound || [strID rangeOfString:#"PNG"].location != NSNotFound )
strImageType = #"png";
NSDateFormatter* df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"MM/dd/yyyy"];
NSString *result = [df stringFromDate:assetDate];
NSTimeInterval timeInterval = [assetDate timeIntervalSince1970];
ALAssetRepresentation *rep = [temp defaultRepresentation];
CGImageRef iref = [rep fullResolutionImage];
StrPath = [StrPath stringByAppendingFormat:#"%d.%#",(int)timeInterval,strImageType];
//UIImage *image = [UIImage imageWithCGImage:[rep fullResolutionImage]];
UIImage *image =[UIImage imageWithCGImage:iref scale:[rep scale] orientation:(UIImageOrientation)[rep orientation]];
//------------------ metadata -------------------------------------------------------
NSDictionary *imageMetadata = [rep metadata];
NSString *strOrt=[NSString stringWithFormat:#"%#",[imageMetadata valueForKey:#"Orientation"]];
NSData *dataObj = nil;
dataObj = UIImageJPEGRepresentation(image, 1.0);
NSString* StrFileData = [Base64 encode:dataObj];
NSString* strFileHash = [dataObj md5Test];
NSMutableDictionary *DictRequest = [[NSMutableDictionary alloc]init];
[DictRequest setObject:srtprefSessionId forKey:#"SessionId"];
[DictRequest setObject:StrPath forKey:#"Path"];
[DictRequest setValue:[NSNumber numberWithBool:isTrash] forKey:#"UploadDirectlyToTrashbin"];
[DictRequest setObject:StrFileData forKey:#"FileData"];
[DictRequest setObject:strFileHash forKey:#"FileHash"];
[DictRequest setObject:result forKey:#"DateCreated"];
BOOL isNULL = [self stringIsEmpty:strOrt];
if(!isNULL)
{
//[DictRequest setObject:strOrt forKey:#"Orientation"];
}
NSString *jsonString = [DictRequest JSONRepresentation];
NSString *strUrl=[NSString stringWithFormat:#"%#",FileUpload_URL];
NSURL *url1=[NSURL URLWithString:strUrl];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url1];
[request setTimeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
NSData *postData = [jsonString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:#"%d",[postData length]];
[request setHTTPBody:postData];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
if(theConnection)
[self Set2Defaults];
theConnection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
[SVProgressHUD dismiss];
if(theConnection)
webData = [NSMutableData data];
else
NSLog(#"Connection Failed !!!");
}
Try this:
-(void)uploadSingleFile
{
#autoreleasepool
{
...
...
}
}
Why need of these many operations ????
NSData *dataObj = nil;
dataObj = UIImageJPEGRepresentation(image, 1.0);
NSString* StrFileData = [Base64 encode:dataObj];
NSString* strFileHash = [dataObj md5Test];
Also I suggest you to compress image before sending, since NSData will be huge. This can be managed from server side
Try compressing image before sending :
CGFloat compression = 0.9f;
NSData *imageData = UIImageJPEGRepresentation([item image], compression);
while ([imageData length] > 700000 && compression > 0.1) {
// NSLog(#"Image size too big, compression more: current data size: %d bytes",[imageData length]);
compression -= 0.1;
imageData = UIImageJPEGRepresentation([item image], compression);
}
Set up the cachePolicy to avoid cache
request.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData