i am trying to develop an downloadmanager. i can now download files from almost anywhere on linkclick.
in the
- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType
i check if the url is a url to a binaryfile like a zipfile. than i setup a nsurlconnection
NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];
[urlRequest setValue:#"User-Agent" forHTTPHeaderField:#"Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en) AppleWebKit/418.9 (KHTML, like Gecko) Safari/419.3"];
NSURLConnection *mainConnection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
if (nil == mainConnection) {
NSLog(#"Could not create the NSURLConnection object");
}
(void)connection:(NSURLConnection )connection didReceiveResponse:(NSURLResponse)response {
self.tabBarController.selectedIndex=1;
[receivedData setLength:0];
percent = 0;
localFilename = [[[url2 absoluteString] lastPathComponent] copy];
NSLog(localFilename);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0] ;
NSString *appFile = [documentsDirectory stringByAppendingPathComponent:localFilename];
[[NSFileManager defaultManager] createFileAtPath:appFile contents:nil attributes:nil];
[downloadname setHidden:NO];
[downloadname setText:localFilename];
expectedBytes = [response expectedContentLength];
exp = [response expectedContentLength];
NSLog(#"content-length: %lli Bytes", expectedBytes);
file = [[NSFileHandle fileHandleForUpdatingAtPath:appFile] retain];
if (file) {
[file seekToEndOfFile];
}
}
(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
if (file) {
[file seekToEndOfFile];
}
[file writeData:data];
[receivedData appendData:data];
long long resourceLength = [receivedData length];
float res = [receivedData length];
percent = res/exp;
[progress setHidden:NO];
[progress setProgress:percent];
NSLog(#"Remaining: %lli KB", (expectedBytes-resourceLength)/1024);
[kbleft setHidden:NO];
[kbleft setText:[NSString stringWithFormat:#"%lli / %lli KB", expectedBytes/1024 ,(resourceLength)/1024]];
}
in the connectiondidfinish loading i close the file. all working fine for nearly every hoster except hosters wich have a capture procedure before like filedude.com
in the uiwebview i can surf to the downloadpage enter the captcha and get the downloadlink. when i click on it the file will be created in the documentsdir with the filename and the download starts but he dont get any data. every file has 0kb and the NSLog(#"content-length: %lli Bytes", expectedBytes); gives out something like 100-400 byte .
can somebody help me solve this problem?
kind regards
Should check what the response is
NSLog(#"%#", [connection allHttpHeaderFields])
Take a look at ASIHttpRequest
http://allseeing-i.com/ASIHTTPRequest/
It is very flexible and reliable. Only if you have truly unique requirements is it a better idea to write your own.
Is it possible that you're not following an HTTP redirect? Have you tried capturing and looking at the data you're actually receiving?
Related
I have a pdf file from server.
Then I need to load the file to NSDocument directory path and its working fine, but i want to show UIProgressView for store each bytes. How to do this , please help me
Thanks in Advance
I tried to store like this:
NSError *error;
NSArray *ipaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *idocumentsDir = [ipaths objectAtIndex:0];
NSString *idataPath = [idocumentsDir stringByAppendingPathComponent:#"File"];
NSLog(#"idataPath:%#",idataPath);
//Create folder here
if (![[NSFileManager defaultManager] fileExistsAtPath:idataPath])
{
[[NSFileManager defaultManager] createDirectoryAtPath:idataPath withIntermediateDirectories:NO attributes:nil error:&error];
}
// Image Download here
NSString *fileName = [idataPath stringByAppendingFormat:#"/image.jpg"];
NSLog(#"imagePathDOWNLOAD:%#",fileName);
NSData *pdfData1 = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:[URLArray objectAtIndex:a]]];
[pdfData1 writeToFile:fileName atomically:YES];
You can use NSURLConnection class to implement progress bar:
.h:
NSMutableData *responseData;
NSString *originalFileSize;
NSString *downloadedFileSize;
.m:
- (void)load {
NSURL *myURL = [NSURL URLWithString:#""];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:myURL
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
responseData = [[NSMutableData alloc] init];
originalFileSize = [response expectedContentLength];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
downloadedFileSize = [responseData length];
progressBar.progress = ([originalFileSize floatValue] / [downloadedFileSize floatValue]);
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[responseData release];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[responseData lengtn]);
}
Let me know for any queries.
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.
i am using NSURLConnection to download mp3 data from the server , my code is here
- (IBAction)downloadData:(id)sender
{
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
NSURL *url = [[NSURL alloc] initWithString:#"http://viadj.viastreaming.net/start/psalmsmedia/ondemand/Nin%20snehamethrayo.mp3"];
[request setURL:url];
[url release];
url = nil;
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
responseData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
[responseData release];
[connection release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"Succeeded! Received %d bytes of data",[responseData
length]);
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"myFile"];
[responseData writeToFile:fileName atomically:YES];
responseData = nil;
self->imageConnection = nil;
}
am little bit confused about the path given to download. when i click download button i shows "Succeeded! Received 1329 bytes of data" but nothing is downloading. need some help. how will we specify the local path of iPhone to store downloaded data?
- (IBAction)downloadData:(id)sender
{
NSURL *url = [[NSURL alloc] initWithString:#"http://viadj.viastreaming.net/start/psalmsmedia/ondemand/Nin%20snehamethrayo.mp3"];
NSMutableURLRequest *theRequest_to = [NSMutableURLRequest requestWithURL:url];
[url release];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:theRequest_to delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response
{
NSString *filepath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"snehamethrayo.mp3"]; // here you can set your filename which you can get from url
[[NSFileManager defaultManager] createFileAtPath:filepath contents:nil attributes:nil];
file = [[NSFileHandle fileHandleForUpdatingAtPath:filepath] retain];// Here file is object of NSFileHandle and its declare in .h File
[file seekToEndOfFile];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[file seekToEndOfFile];
[file writeData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
[file closeFile];
}
No need for any code change I think.Just put an nslog and see...
NSString *fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"myFile"];
NSLog(#"%#",fileName);
That will list the file location like this
/Users/me/Library/Application Support/iPhone Simulator/5.0/Applications/(your app)/Documents/myFile. ie the downloaded file is in your document folder.
note: don't forget to put the file format ie
NSString *fileName = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"myFile.mp3"];
I'm developing a new iPhone application, Here i have parsed a 'csv' file from local, and its working with me. When i try to download the 'csv' file from the server programmatically, it didn't workout for me. Could you please help me?
Loading data from local file (Working fine)
- (void)viewDidLoad
{
[super viewDidLoad];
NSString * file = [[NSBundle bundleForClass:[self class]] pathForResource:#"sample" ofType:#"csv"];
NSStringEncoding encoding = 0;
NSString * csv = [NSString stringWithContentsOfFile:file usedEncoding:&encoding error:nil];
NSArray *fields = [csv CSVComponents];
NSLog(#"fields: %#", fields); //getting the result content
}
Download the file from Server (failed)
-(void) connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(#"connectionDidFinishLoading"); //nothing showing here
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *fullName = [NSString stringWithFormat:#"quotes.csv"];
NSString *fullFilePath = [NSString stringWithFormat:#"%#/%#",docDir,fullName];
[receivedData writeToFile:fullFilePath atomically:YES];
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
NSLog(#"data: %#", data); //nothing showing here
if (receivedData)
[receivedData appendData:data];
else
receivedData = [[NSMutableData alloc] initWithData:data];
}
- (void)loadDatafromURL
{
NSURL *url = [NSURL URLWithString:#"http://download.finance.yahoo.com/d/quotes.csv?s=^GSPC,^IXIC,^dji,^GSPC,^BVSP,^GSPTSE,^FTSE,^GDAXI,^FCHI,^STOXX50E,^AEX,^IBEX,^SSMI,^N225,^AXJO,^HSI,^NSEI&f=sl1d1t1c1ohgv&e=.csv"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection connectionWithRequest:request delegate:self];
}
Implement this method:
-(void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
You'll find that you're getting an error of
Error Domain=NSURLErrorDomain Code=-1000 "bad URL" UserInfo=0xf663f40 {NSUnderlyingError=0xf663de0 "bad URL", NSLocalizedDescription=bad URL}
I've looked into downloading information this way before, and I think one problem you're having is that separate symbols have to be separated with a "+". Also, when pulling an index, you can't pass the "^" symbol as part of the URL. You have to replace it with "%5E".
So, add this:
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"%#", [error description]);
}
And change your URL to this:
NSString *urlString = #"http://download.finance.yahoo.com/d/quotes.csv?s=^GSPC+^IXIC+^dji+^GSPC+^BVSP+^GSPTSE+^FTSE+^GDAXI+^FCHI+^STOXX50E+^AEX+^IBEX+^SSMI+^N225+^AXJO+^HSI+^NSEI&f=sl1d1t1c1ohgv&e=.csv";
NSURL *url = [NSURL URLWithString:[urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
Now it works for me! I even checked the output .csv file, and it looks good to go! One full quote per line.
If you plan on fetching more data over the network than this single csv, you could have a look at AFNetworking, it's a great library for doing network operations.
A working solution would then look a bit like this:
- (void)getCSVAsynch {
NSString *unescaped = #"http://download.finance.yahoo.com/d/quotes.csv?s=^GSPC,^IXIC,^dji,^GSPC,^BVSP,^GSPTSE,^FTSE,^GDAXI,^FCHI,^STOXX50E,^AEX,^IBEX,^SSMI,^N225,^AXJO,^HSI,^NSEI&f=sl1d1t1c1ohgv&e=.csv";
NSURL *url = [NSURL URLWithString:[unescaped stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"CSV: %#", [[NSString alloc] initWithBytes:[responseObject bytes] length:[responseObject length] encoding:NSUTF8StringEncoding]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Things go boom. %#", [error localizedDescription]);
}];
[operation start];
}
I encounter a problem by following your comment. I would like to download different file at same time with different delegate:
.h:
NSMutableData *fileData;
.m:
NSString *imgfile = [NSString stringWithFormat:#"http://xxxx/01.jpg"];
NSURL *fileURL1 = [NSURL URLWithString:imgfile];
NSString *audiofile = [NSString stringWithFormat:#"http://xxxx/01.mp3"];
NSURL *fileURL2 = [NSURL URLWithString:audiofile];
NSURLRequest *request1 = [NSURLRequest requestWithURL:fileURL1 cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0 ];
NSURLRequest *request2 = [NSURLRequest requestWithURL:fileURL2 cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0 ];
NSArray *connections = [[NSArray alloc] initWithObjects:
[[NSURLConnection alloc] initWithRequest:request1 delegate:self ],
[[NSURLConnection alloc] initWithRequest:request2 delegate:self ],
nil];
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
fileData = [[NSMutableData alloc] init];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[fileData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(#"Unable to fetch data");
}
ok, the download process works, but, the file size of jpg and mp3 are incorrect, the only correct thing is the total file size (jpg+mp3), please could you have a look on the code, what is missing?
Another question is, I put the file in a NSMutableArray, my question is, how to check which index of array is the correct file type (jpg and mp3)? because I need to save them to the device folder.
It looks like both your connections write to the same fileData object and all your problems follow from that.
How to deal with multiple connections you can see relevant question asked here on SO, there's also nice blog post containing NSURLConnection subclass that addresses this issue.
Here is what I am doing, I set a counter to identify the file type to save:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSMutableData *dataForConnection = [self dataForConnection:(CustomURLConnection*)connection];
[connection release];
// Do something with the dataForConnection.
downloadCount ++;
// Copy Image Data to ur location using FileManager
//UIImage *img = [UIImage imageWithData:fileData];
NSString *saveDir;
if (downloadCount ==1)
saveDir = [NSString stringWithFormat:#"001.jpg"];
if (downloadCount == 2)
saveDir = [NSString stringWithFormat:#"001.mp3"];
//NSLog(#"saveDir=%#",saveDir);
NSArray * sysPaths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES );
NSString * filePath = [[NSString alloc] initWithFormat: #"%#/%#", [sysPaths objectAtIndex: 0], saveDir];
NSLog(#"filePath=%#",filePath);
if([dataForConnection writeToFile:filePath atomically:YES])
NSLog(#"DONE COPYING");
else
NSLog(#"Write to device error");
//[fileData setLength:0];
if (downloadCount == 2)
{
downloadCount = 0;
play the MP3 and display the image file;
}
}
even I run the app on simulator, the file was download without error reported, but sometimes the file can not be opened, even I tried to open it from the folder, I was told the file was corrupted, I do not understand what was wrong, hope you do understand what I am saying.