download multiple files on iphone - iphone

i want to download file(s) from web server.
Scenario:
As user will select row (file name- user can select 1 or more files to download) and and press download, i am getting URL for each file(all have different URL) and storing into pathArray.
and doing following
-(void)downloadFile {
for (int i = 0; i<[pathArray count]; i++) {
NSURL *fileURL = [NSURL fileURLWithPath:[pathArray objectAtIndex:i]];
NSString *ResultURL = [fileURL absoluteString];
NSURL *url = [[NSURL alloc] initWithString:ResultURL];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL: url
cachePolicy: NSURLRequestReloadIgnoringCacheData timeoutInterval: 60.0];
conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
if (conn) {
NSLog(#"*************CONNECTED************");
webData = [[NSMutableData data] retain];
NSLog(#"weblength : %d : ", [webData length]);
downloadTag = YES;
} else {
NSLog(#"*************Connection NOT DONE************");
downloadTag=NO;
}
}
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(#"*************Try to receive data************");
[webData appendData:data];
NSLog(#"weblength : %d : ", [webData length]);
NSLog(#"*************Data Received an append too ***********");
if (downloadTag == YES) {
paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
self.documentsDir = [[paths objectAtIndex:0]stringByAppendingPathComponent:#"NewResult.zip" ];
[[NSFileManager defaultManager] createFileAtPath:documentsDir contents:nil attributes:nil];
NSFileHandle *file1 = [NSFileHandle fileHandleForUpdatingAtPath: documentsDir];
[file1 writeData: webData];
NSLog(#"Webdata : %d",[webData length]);
[file1 closeFile];
}
}
if i am not using for loop i.e only one file download then it work fine but not with for loop....its really important for me to solve this issue.
thank you very much

take a look at ASIHTTPRequest, it has a nice queue for downloading and monitoring progress http://allseeing-i.com/ASIHTTPRequest/How-to-use

You're using asynchronous downloads, but the delegate for each download item is the same object, causing all of the downloaded data to get appended to the same file. The way I do it is to have a small Object (DownloadQueueItem) that is the delegate for a single download. When you download another file, you create a new DownloadQueueItem and it handles everything.
Edit:
Q: instead of %i putting by my self i am searching is there any way to create new file every time like if ""NewResult.zip" is exist then create "NewResult1.zip" and so on
A: You could do something like this:
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filename = #"NewResult%#.zip";
for (int i = 0; ; i++) {
NSString *filename = NULL;
if (i == 0) {
filename = [NSString stringWithFormat:filename, #""];
}
else {
filename = [NSString stringWithFormat:filename, [NSString stringWithFormat:#"%i", i]];
}
if (![[NSFileManager defaultManager] fileExistsAtPath:filename]) {
// Save file.
break;
}
}

Related

Download file from URL and place it in Resource folder in iPhone

I am new to iPhone developer,
How can i download the epub file from url and store it in Resource folder ?
Here is my code snippet,
- (void)viewDidLoad
{
[super viewDidLoad];
fileData = [NSMutableData data];
NSString *file = [NSString stringWithFormat:#"http://www.google.co.in/url?sa=t&rct=j&q=sample%20epub%20filetype%3Aepub&source=web&cd=2&ved=0CFMQFjAB&url=http%3A%2F%2Fdl.dropbox.com%2Fu%2F1177388%2Fflagship_july_4_2010_flying_island_press.epub&ei=i5gHUIOWJI3RrQeGro3YAg&usg=AFQjCNFPKsV-tieF4vKv7BXYmS-QEvd7Uw"];
NSURL *fileURL = [NSURL URLWithString:file];
NSURLRequest *req = [NSURLRequest requestWithURL:fileURL];
NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[self.fileData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[self.fileData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"%#", [dirArray objectAtIndex:0]);
NSString *path = [NSString stringWithFormat:#"%#", [dirArray objectAtIndex:0]];
if ([self.fileData writeToFile:path options:NSAtomicWrite error:nil] == NO) {
NSLog(#"writeToFile error");
}
else {
NSLog(#"Written!");
}
}
I am not able to see anything in my NSLog.
There is a problem in creation of file path also while writing. you have not specified any filename in the path. In the below line, I have used file name as "filename.txt". Give some proper name and it will write.
NSString *path = [NSString stringWithFormat:#"%#/filename.txt", [dirArray objectAtIndex:0]];
There is a problem in creating URL also. Do it like this,
NSString *file = [NSString stringWithString:#"http://www.google.co.in/url?sa=t&rct=j&q=sample%20epub%20filetype%3Aepub&source=web&cd=2&ved=0CFMQFjAB&url=http%3A%2F%2Fdl.dropbox.com%2Fu%2F1177388%2Fflagship_july_4_2010_flying_island_press.epub&ei=i5gHUIOWJI3RrQeGro3YAg&usg=AFQjCNFPKsV-tieF4vKv7BXYmS-QEvd7Uw"];
NSURL *fileURL = [NSURL URLWithString:file];
You have created your file data with below line.
fileData = [NSMutableData data];
Make it like below,
fileData = [[NSMutableData alloc]init];
OR
self.fileData = [NSMutableData data];
Here iOS releases filedata before your connection delegate get called.

iPhone - How to download big amount of files

I need to download a number of files from the server. What is the best way to do it?
All documents are stored in NSMutableArray and for each documents there are two files - the document itself and its change log. So what I do is:
- (void)downloadDocuments:(int)docNumber
{
NSString *urlString;
NSURL *url;
for (int i=0; i<[items count]; i++) {
[progressBar setProgress:((float)i/[items count]) animated:YES];
urlString = [[items objectAtIndex:i] docUrl];
url = [[NSURL alloc] initWithString:[urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
[self downloadSingleDocument:url];
urlString = [[items objectAtIndex:i] changeLogUrl];
url = [[NSURL alloc] initWithString:[urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
[self downloadSingleDocument:url];
}
urlString = nil;
url = nil;
[self dismissModalViewControllerAnimated:YES];
}
- (void)downloadSingleDocument:(NSURL *)url
{
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
[req addValue:#"Basic XXXXXXX=" forHTTPHeaderField:#"Authorization"];
downloadConnection = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)response
{
if (conn == downloadConnection) {
NSString *filename = [[conn.originalRequest.URL absoluteString] lastPathComponent];
filename = [filename stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
filePath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:filename];
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
file = [[NSFileHandle fileHandleForUpdatingAtPath:filePath] retain];
if (file)
{
[file seekToEndOfFile];
}
}
}
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
if (conn == downloadConnection) {
if (file) {
[file seekToEndOfFile];
}
[file writeData:data];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
if (conn==downloadConnection) {
[file closeFile];
}
}
And my problem is that only the last file is downloaded. Any suggestions on what I am doing wrong?
Thanks in advance for help!
The problem is that you "overwrite" the member var "downloadConnection" within your loop with a new instance of NSURLConnection (through method call downloadSingleDocument). Doing this leads to the case that the if-statements within your didReceiveResponse, didReceiveData and connectionDidFinish methods will only evaluate to true with the latest created connection. Try using a list of connections to avoid this.

NSMutableData Save to a File

I downloaed the file using code shown below. Then i am trying to save NSMutableData variable to file, however, the file is not created. What am i doing wrong? Do i need to convert NSMutableData into NSString?
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)_response {
response = [_response retain];
if([response expectedContentLength] < 1) {
data = [[NSMutableData alloc] init];
}
else {
data = [[NSMutableData dataWithCapacity:[response expectedContentLength]] retain];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)_data {
[data appendData:_data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"file" ofType:#"txt"];
NSLog(#"saved: %#", filePath);
[data writeToFile:filePath atomically:YES];
NSLog(#"downloaded file: %#", data); //all i see in log is some encoded data here
}
You can’t write inside your app’s bundle. You’ll need to save it somewhere else, like your app’s Documents directory:
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:#"file.txt"];
[data writeToFile:filePath atomically:YES];

Copy XML file from Server to iphone?

I want to copy the xml file from server to save it to locally, because if I will send request to server again and again, it will take time, so I want to copy the xml to local resources whenever app starts, then parse the local xml,
how can I do it?
First of all you need to download the file:
NSURL *url = [NSURL URLWithString:FILEURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
then add in the h file:
NSMutableData *receivedData;
and in the m file:
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (receivedData)
{
[receivedData appendData:data];
}
else
{
receivedData = [[NSMutableData alloc] initWithData:data];
}
}
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
//saving your data in the local
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullName = [NSString stringWithFormat:#"xmlfile.xml"];
NSString *fullFilePath = [NSString stringWithFormat:#"%#/%#",docDir,fullName];
[receivedData writeToFile:fullFilePath atomically:YES];
}
edit:
get the file from local-
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullName = [NSString stringWithFormat:#"xmlfile.xml"];
NSString *fullFilePath = [NSString stringWithFormat:#"%#/%#",docDir,fullName];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
now you can take the NSData when parse it,there are a lot of examples in the site.

downloading files using UI web view

Is it possible to download files implementing UI web iphone in my app? If so where would the files be stored and how can I access it?
You can't really download files simply by browsing to them but what you could do is use
(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
to analyze the link for a file (say by looking at the extension of last path component) and if you want this kind of file to be downloaded than you could use [NSURLConnection connectionWithRequest:myURLRequest delegate:self]; and all its associated delegate methods to download and store the file in the documents folder.
if you want to visualize some known for webview file, it will show you automatically...but if page give back an unknown for webview file (This happened to me with Citrix ica file) webview will give you an error....to solve this problem i used this code (note that here i will allow to download only ica file, but you can change this condition):
-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
if([error code]!=102)
{ [self.lblError setText:[NSString stringWithFormat:#"%#",error]];
return;
}
NSDictionary *userInfo = [error userInfo];
NSString * url = [[NSString alloc] initWithFormat:#"%#",[userInfo objectForKey:#"NSErrorFailingURLKey"] ];
NSString *search = #"?";
NSRange result = [url rangeOfString:search];
NSInteger startingPosition;
NSString *fileName,*fileExtention,*fileLocation;
if (result.location != NSNotFound) {
startingPosition = result.location + result.length;
fileLocation = [url substringToIndex:result.location];
fileExtention=[fileLocation pathExtension];
}
else
{
fileLocation=url;
}
fileName = [fileLocation lastPathComponent];
fileExtention=[fileLocation pathExtension];
//check if file to download if ica file
if(![fileExtention isEqualToString:#"ica"])
return;
self.lblError.textColor=[UIColor blackColor];
self.lblError.text=[NSString stringWithFormat:#"downloading %#...",fileName];
NSURL * _url = [[NSURL alloc] initWithString:url];
// Get file online
NSData *fileOnline = [[NSData alloc] initWithContentsOfURL:_url];
// Write file to the Documents directory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
if (!documentsDirectory) {
// NSLog(#"Documents directory not found!");
return;
}
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:fileName];
//NSLog(#"appFile path: %#",appFile);
[fileOnline writeToFile:appFile atomically:YES];
NSURL* aUrl = [NSURL fileURLWithPath:appFile];
self.interactionController = [UIDocumentInteractionController interactionControllerWithURL: aUrl];
self.interactionController.delegate = self;
self.lblError.text=[NSString stringWithFormat:#"%# downloaded",fileName];
[self.interactionController presentOpenInMenuFromRect:self.lblError.frame inView:self.view animated:YES];
}